Merge from emacs-23
[bpt/emacs.git] / lisp / net / net-utils.el
CommitLineData
e8af40ee 1;;; net-utils.el --- network functions
8749abea 2
a2e01f7e 3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
5df4f04c 4;; 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
a84f13fb 5
8749abea
GM
6;; Author: Peter Breton <pbreton@cs.umb.edu>
7;; Created: Sun Mar 16 1997
c2e6c8d1 8;; Keywords: network comm
8749abea
GM
9
10;; This file is part of GNU Emacs.
11
874a927a 12;; GNU Emacs is free software: you can redistribute it and/or modify
8749abea 13;; it under the terms of the GNU General Public License as published by
874a927a
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
8749abea
GM
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
874a927a 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
8749abea
GM
24
25;;; Commentary:
c2e6c8d1 26
8749abea
GM
27;;
28;; There are three main areas of functionality:
ddb62bf1 29;;
8749abea
GM
30;; * Wrap common network utility programs (ping, traceroute, netstat,
31;; nslookup, arp, route). Note that these wrappers are of the diagnostic
32;; functions of these programs only.
ddb62bf1 33;;
8749abea 34;; * Implement some very basic protocols in Emacs Lisp (finger and whois)
ddb62bf1 35;;
8749abea
GM
36;; * Support connections to HOST/PORT, generally for debugging and the like.
37;; In other words, for doing much the same thing as "telnet HOST PORT", and
38;; then typing commands.
39;;
40;; PATHS
41;;
42;; On some systems, some of these programs are not in normal user path,
ddb62bf1 43;; but rather in /sbin, /usr/sbin, and so on.
8749abea
GM
44
45
46;;; Code:
8749abea
GM
47
48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49;; Customization Variables
50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51
52(defgroup net-utils nil
53 "Network utility functions."
54 :prefix "net-utils-"
55 :group 'comm
c2e6c8d1 56 :version "20.3")
8749abea 57
17731c39 58(defcustom net-utils-remove-ctl-m (memq system-type '(windows-nt msdos))
8749abea
GM
59 "If non-nil, remove control-Ms from output."
60 :group 'net-utils
c2e6c8d1 61 :type 'boolean)
8749abea 62
ddb62bf1
PB
63(defcustom traceroute-program
64 (if (eq system-type 'windows-nt)
8749abea
GM
65 "tracert"
66 "traceroute")
67 "Program to trace network hops to a destination."
68 :group 'net-utils
c2e6c8d1 69 :type 'string)
8749abea
GM
70
71(defcustom traceroute-program-options nil
72 "Options for the traceroute program."
73 :group 'net-utils
c2e6c8d1 74 :type '(repeat string))
8749abea
GM
75
76(defcustom ping-program "ping"
77 "Program to send network test packets to a host."
78 :group 'net-utils
c2e6c8d1 79 :type 'string)
8749abea 80
c2e6c8d1 81;; On GNU/Linux and Irix, the system's ping program seems to send packets
8749abea 82;; indefinitely unless told otherwise
ddb62bf1 83(defcustom ping-program-options
17731c39 84 (and (memq system-type '(gnu/linux irix))
8749abea
GM
85 (list "-c" "4"))
86 "Options for the ping program.
87These options can be used to limit how many ICMP packets are emitted."
88 :group 'net-utils
c2e6c8d1 89 :type '(repeat string))
8749abea 90
cd6ef82d
GM
91(define-obsolete-variable-alias 'ipconfig-program 'ifconfig-program "22.2")
92
46f6fa95 93(defcustom ifconfig-program
8749abea
GM
94 (if (eq system-type 'windows-nt)
95 "ipconfig"
96 "ifconfig")
97 "Program to print network configuration information."
98 :group 'net-utils
c2e6c8d1 99 :type 'string)
8749abea 100
af3ccb5c
GM
101(define-obsolete-variable-alias 'ipconfig-program-options
102 'ifconfig-program-options "22.2")
103
46f6fa95 104(defcustom ifconfig-program-options
c2e6c8d1
PJ
105 (list
106 (if (eq system-type 'windows-nt)
107 "/all" "-a"))
2f7dc12d 108 "Options for the ifconfig program."
8749abea 109 :group 'net-utils
c2e6c8d1 110 :type '(repeat string))
8749abea 111
e69ec721
GM
112(defcustom iwconfig-program "iwconfig"
113 "Program to print wireless network configuration information."
114 :group 'net-utils
beaa23bc
GM
115 :type 'string
116 :version "23.1")
e69ec721
GM
117
118(defcustom iwconfig-program-options nil
20f28123 119 "Options for the iwconfig program."
e69ec721 120 :group 'net-utils
beaa23bc
GM
121 :type '(repeat string)
122 :version "23.1")
e69ec721 123
2f7dc12d 124(defcustom netstat-program "netstat"
8749abea
GM
125 "Program to print network statistics."
126 :group 'net-utils
c2e6c8d1 127 :type 'string)
8749abea 128
ddb62bf1 129(defcustom netstat-program-options
8749abea 130 (list "-a")
2f7dc12d 131 "Options for the netstat program."
8749abea 132 :group 'net-utils
c2e6c8d1 133 :type '(repeat string))
8749abea 134
2f7dc12d 135(defcustom arp-program "arp"
8749abea
GM
136 "Program to print IP to address translation tables."
137 :group 'net-utils
c2e6c8d1 138 :type 'string)
8749abea 139
ddb62bf1 140(defcustom arp-program-options
8749abea 141 (list "-a")
2f7dc12d 142 "Options for the arp program."
8749abea 143 :group 'net-utils
c2e6c8d1 144 :type '(repeat string))
8749abea 145
ddb62bf1 146(defcustom route-program
8749abea
GM
147 (if (eq system-type 'windows-nt)
148 "route"
149 "netstat")
150 "Program to print routing tables."
151 :group 'net-utils
c2e6c8d1 152 :type 'string)
8749abea 153
ddb62bf1 154(defcustom route-program-options
8749abea
GM
155 (if (eq system-type 'windows-nt)
156 (list "print")
157 (list "-r"))
2f7dc12d 158 "Options for the route program."
8749abea 159 :group 'net-utils
c2e6c8d1 160 :type '(repeat string))
8749abea 161
2f7dc12d 162(defcustom nslookup-program "nslookup"
8749abea
GM
163 "Program to interactively query DNS information."
164 :group 'net-utils
c2e6c8d1 165 :type 'string)
8749abea 166
2f7dc12d
JB
167(defcustom nslookup-program-options nil
168 "Options for the nslookup program."
8749abea 169 :group 'net-utils
c2e6c8d1 170 :type '(repeat string))
8749abea
GM
171
172(defcustom nslookup-prompt-regexp "^> "
8fb051f9
MB
173 "Regexp to match the nslookup prompt.
174
175This variable is only used if the variable
980cc247 176`comint-use-prompt-regexp' is non-nil."
8749abea 177 :group 'net-utils
c2e6c8d1 178 :type 'regexp)
8749abea 179
2f7dc12d 180(defcustom dig-program "dig"
8749abea
GM
181 "Program to query DNS information."
182 :group 'net-utils
c2e6c8d1 183 :type 'string)
8749abea
GM
184
185(defcustom ftp-program "ftp"
2f7dc12d 186 "Program to run to do FTP transfers."
8749abea 187 :group 'net-utils
c2e6c8d1 188 :type 'string)
8749abea
GM
189
190(defcustom ftp-program-options nil
2f7dc12d 191 "Options for the ftp program."
8749abea 192 :group 'net-utils
c2e6c8d1 193 :type '(repeat string))
8749abea
GM
194
195(defcustom ftp-prompt-regexp "^ftp>"
8fb051f9
MB
196 "Regexp which matches the FTP program's prompt.
197
198This variable is only used if the variable
980cc247 199`comint-use-prompt-regexp' is non-nil."
8749abea 200 :group 'net-utils
c2e6c8d1 201 :type 'regexp)
8749abea
GM
202
203(defcustom smbclient-program "smbclient"
204 "Smbclient program."
205 :group 'net-utils
c2e6c8d1 206 :type 'string)
8749abea
GM
207
208(defcustom smbclient-program-options nil
2f7dc12d 209 "Options for the smbclient program."
8749abea 210 :group 'net-utils
c2e6c8d1 211 :type '(repeat string))
8749abea
GM
212
213(defcustom smbclient-prompt-regexp "^smb: \>"
8fb051f9
MB
214 "Regexp which matches the smbclient program's prompt.
215
216This variable is only used if the variable
980cc247 217`comint-use-prompt-regexp' is non-nil."
8749abea 218 :group 'net-utils
c2e6c8d1 219 :type 'regexp)
8749abea 220
2f7dc12d 221(defcustom dns-lookup-program "host"
ac8a1898
PB
222 "Program to interactively query DNS information."
223 :group 'net-utils
2f7dc12d 224 :type 'string)
ac8a1898 225
2f7dc12d
JB
226(defcustom dns-lookup-program-options nil
227 "Options for the dns-lookup program."
ac8a1898 228 :group 'net-utils
2f7dc12d 229 :type '(repeat string))
ac8a1898 230
76540917
PB
231;; Internal variables
232(defvar network-connection-service nil)
233(defvar network-connection-host nil)
234
8749abea
GM
235;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
236;; Nslookup goodies
237;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
238
ce299d55 239(defvar nslookup-font-lock-keywords
cbbe9a37
GM
240 (list
241 (list "^[A-Za-z0-9 _]+:" 0 'font-lock-type-face)
242 (list "\\<\\(SOA\\|NS\\|MX\\|A\\|CNAME\\)\\>"
243 1 'font-lock-keyword-face)
244 ;; Dotted quads
245 (list
246 (mapconcat 'identity
247 (make-list 4 "[0-9]+")
248 "\\.")
249 0 'font-lock-variable-name-face)
250 ;; Host names
251 (list
252 (let ((host-expression "[-A-Za-z0-9]+"))
253 (concat
254 (mapconcat 'identity
255 (make-list 2 host-expression)
256 "\\.")
257 "\\(\\." host-expression "\\)*"))
258 0 'font-lock-variable-name-face))
3478046b 259 "Expressions to font-lock for nslookup.")
8749abea 260
ce299d55
CY
261;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
262;; General network utilities mode
263;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264
265(defvar net-utils-font-lock-keywords
266 (list
267 ;; Dotted quads
268 (list
269 (mapconcat 'identity (make-list 4 "[0-9]+") "\\.")
270 0 'font-lock-variable-name-face)
271 ;; Simple rfc4291 addresses
272 (list (concat
273 "\\( \\([[:xdigit:]]+\\(:\\|::\\)\\)+[[:xdigit:]]+\\)"
274 "\\|"
275 "\\(::[[:xdigit:]]+\\)")
276 0 'font-lock-variable-name-face)
277 ;; Host names
278 (list
279 (let ((host-expression "[-A-Za-z0-9]+"))
280 (concat
281 (mapconcat 'identity (make-list 2 host-expression) "\\.")
282 "\\(\\." host-expression "\\)*"))
283 0 'font-lock-variable-name-face))
284 "Expressions to font-lock for general network utilities.")
285
286(define-derived-mode net-utils-mode special-mode "NetworkUtil"
287 "Major mode for interacting with an external network utility."
288 (set (make-local-variable 'font-lock-defaults)
289 '((net-utils-font-lock-keywords))))
290
8749abea
GM
291;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
292;; Utility functions
293;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294
295;; Simplified versions of some at-point functions from ffap.el.
296;; It's not worth loading all of ffap just for these.
297(defun net-utils-machine-at-point ()
298 (let ((pt (point)))
299 (buffer-substring-no-properties
300 (save-excursion
301 (skip-chars-backward "-a-zA-Z0-9.")
302 (point))
303 (save-excursion
304 (skip-chars-forward "-a-zA-Z0-9.")
305 (skip-chars-backward "." pt)
306 (point)))))
307
308(defun net-utils-url-at-point ()
309 (let ((pt (point)))
310 (buffer-substring-no-properties
311 (save-excursion
312 (skip-chars-backward "--:=&?$+@-Z_a-z~#,%")
313 (skip-chars-forward "^A-Za-z0-9" pt)
314 (point))
315 (save-excursion
316 (skip-chars-forward "--:=&?$+@-Z_a-z~#,%")
317 (skip-chars-backward ":;.,!?" pt)
318 (point)))))
319
8749abea
GM
320(defun net-utils-remove-ctrl-m-filter (process output-string)
321 "Remove trailing control Ms."
322 (let ((old-buffer (current-buffer))
323 (filtered-string output-string))
324 (unwind-protect
325 (let ((moving))
326 (set-buffer (process-buffer process))
ce299d55
CY
327 (let ((inhibit-read-only t))
328 (setq moving (= (point) (process-mark process)))
329
330 (while (string-match "\r" filtered-string)
331 (setq filtered-string
332 (replace-match "" nil nil filtered-string)))
333
334 (save-excursion
335 ;; Insert the text, moving the process-marker.
336 (goto-char (process-mark process))
337 (insert filtered-string)
338 (set-marker (process-mark process) (point))))
8749abea
GM
339 (if moving (goto-char (process-mark process))))
340 (set-buffer old-buffer))))
ddb62bf1 341
20f28123 342(defun net-utils-run-program (name header program args)
8749abea 343 "Run a network information program."
20f28123
JB
344 (let ((buf (get-buffer-create (concat "*" name "*"))))
345 (set-buffer buf)
346 (erase-buffer)
347 (insert header "\n")
348 (set-process-filter
349 (apply 'start-process name buf program args)
350 'net-utils-remove-ctrl-m-filter)
351 (display-buffer buf)
352 buf))
8749abea 353
ce299d55
CY
354;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355;; General network utilities (diagnostic)
356;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
357
358(defun net-utils-run-simple (buffer-name program-name args)
359 "Run a network utility for diagnostic output only."
360 (interactive)
361 (when (get-buffer buffer-name)
362 (kill-buffer buffer-name))
363 (get-buffer-create buffer-name)
364 (with-current-buffer buffer-name
365 (net-utils-mode)
366 (set-process-filter
367 (apply 'start-process (format "%s" program-name)
368 buffer-name program-name args)
369 'net-utils-remove-ctrl-m-filter)
370 (goto-char (point-min)))
371 (display-buffer buffer-name))
372
373;;;###autoload
5a0c3f56
JB
374(defun ifconfig ()
375 "Run ifconfig and display diagnostic output."
376 (interactive)
377 (net-utils-run-simple
378 (format "*%s*" ifconfig-program)
379 ifconfig-program
ce299d55
CY
380 ifconfig-program-options))
381
382(defalias 'ipconfig 'ifconfig)
383
384;;;###autoload
5a0c3f56
JB
385(defun iwconfig ()
386 "Run iwconfig and display diagnostic output."
387 (interactive)
388 (net-utils-run-simple
389 (format "*%s*" iwconfig-program)
390 iwconfig-program
ce299d55
CY
391 iwconfig-program-options))
392
393;;;###autoload
394(defun netstat ()
5a0c3f56 395 "Run netstat and display diagnostic output."
ce299d55
CY
396 (interactive)
397 (net-utils-run-simple
398 (format "*%s*" netstat-program)
399 netstat-program
400 netstat-program-options))
401
402;;;###autoload
403(defun arp ()
5a0c3f56 404 "Run arp and display diagnostic output."
ce299d55
CY
405 (interactive)
406 (net-utils-run-simple
407 (format "*%s*" arp-program)
408 arp-program
409 arp-program-options))
410
411;;;###autoload
412(defun route ()
413 "Run route and display diagnostic output."
414 (interactive)
415 (net-utils-run-simple
416 (format "*%s*" route-program)
417 route-program
418 route-program-options))
419
8749abea
GM
420;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
421;; Wrappers for external network programs
422;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
423
424;;;###autoload
425(defun traceroute (target)
426 "Run traceroute program for TARGET."
427 (interactive "sTarget: ")
ddb62bf1 428 (let ((options
8749abea
GM
429 (if traceroute-program-options
430 (append traceroute-program-options (list target))
431 (list target))))
432 (net-utils-run-program
433 (concat "Traceroute" " " target)
434 (concat "** Traceroute ** " traceroute-program " ** " target)
435 traceroute-program
c2e6c8d1 436 options)))
8749abea
GM
437
438;;;###autoload
439(defun ping (host)
440 "Ping HOST.
ddb62bf1 441If your system's ping continues until interrupted, you can try setting
8749abea 442`ping-program-options'."
ddb62bf1 443 (interactive
8749abea 444 (list (read-from-minibuffer "Ping host: " (net-utils-machine-at-point))))
ddb62bf1 445 (let ((options
8749abea
GM
446 (if ping-program-options
447 (append ping-program-options (list host))
448 (list host))))
449 (net-utils-run-program
450 (concat "Ping" " " host)
451 (concat "** Ping ** " ping-program " ** " host)
452 ping-program
c2e6c8d1 453 options)))
8749abea 454
8749abea
GM
455;; FIXME -- Needs to be a process filter
456;; (defun netstat-with-filter (filter)
457;; "Run netstat program."
458;; (interactive "sFilter: ")
459;; (netstat)
460;; (set-buffer (get-buffer "*Netstat*"))
461;; (goto-char (point-min))
c2e6c8d1 462;; (delete-matching-lines filter))
8749abea
GM
463
464;;;###autoload
465(defun nslookup-host (host)
466 "Lookup the DNS information for HOST."
467 (interactive
468 (list (read-from-minibuffer "Lookup host: " (net-utils-machine-at-point))))
ddb62bf1 469 (let ((options
8749abea
GM
470 (if nslookup-program-options
471 (append nslookup-program-options (list host))
472 (list host))))
473 (net-utils-run-program
474 "Nslookup"
475 (concat "** "
476 (mapconcat 'identity
477 (list "Nslookup" host nslookup-program)
478 " ** "))
479 nslookup-program
c2e6c8d1 480 options)))
8749abea
GM
481
482;;;###autoload
483(defun nslookup ()
484 "Run nslookup program."
485 (interactive)
a2e01f7e 486 (switch-to-buffer (make-comint "nslookup" nslookup-program))
c2e6c8d1 487 (nslookup-mode))
8749abea 488
cbbe9a37
GM
489(defvar comint-prompt-regexp)
490(defvar comint-input-autoexpand)
491
492(autoload 'comint-mode "comint" nil t)
493
8749abea 494;; Using a derived mode gives us keymaps, hooks, etc.
8fb051f9 495(define-derived-mode nslookup-mode comint-mode "Nslookup"
8749abea 496 "Major mode for interacting with the nslookup program."
ddb62bf1 497 (set
8749abea
GM
498 (make-local-variable 'font-lock-defaults)
499 '((nslookup-font-lock-keywords)))
8749abea 500 (setq comint-prompt-regexp nslookup-prompt-regexp)
c2e6c8d1 501 (setq comint-input-autoexpand t))
8749abea
GM
502
503(define-key nslookup-mode-map "\t" 'comint-dynamic-complete)
504
ac8a1898
PB
505;;;###autoload
506(defun dns-lookup-host (host)
507 "Lookup the DNS information for HOST (name or IP address)."
508 (interactive
509 (list (read-from-minibuffer "Lookup host: " (net-utils-machine-at-point))))
510 (let ((options
511 (if dns-lookup-program-options
512 (append dns-lookup-program-options (list host))
513 (list host))))
514 (net-utils-run-program
515 (concat "DNS Lookup [" host "]")
516 (concat "** "
517 (mapconcat 'identity
518 (list "DNS Lookup" host dns-lookup-program)
519 " ** "))
520 dns-lookup-program
cbbe9a37
GM
521 options)))
522
523(autoload 'ffap-string-at-point "ffap")
ac8a1898 524
8749abea 525;;;###autoload
5daebfbb 526(defun run-dig (host)
8749abea
GM
527 "Run dig program."
528 (interactive
529 (list
cbbe9a37
GM
530 (read-from-minibuffer "Lookup host: "
531 (or (ffap-string-at-point 'machine) ""))))
8749abea
GM
532 (net-utils-run-program
533 "Dig"
534 (concat "** "
535 (mapconcat 'identity
536 (list "Dig" host dig-program)
537 " ** "))
538 dig-program
c2e6c8d1 539 (list host)))
8749abea 540
cbbe9a37
GM
541(autoload 'comint-exec "comint")
542
8749abea
GM
543;; This is a lot less than ange-ftp, but much simpler.
544;;;###autoload
545(defun ftp (host)
546 "Run ftp program."
ddb62bf1 547 (interactive
8749abea 548 (list
ddb62bf1 549 (read-from-minibuffer
8749abea 550 "Ftp to Host: " (net-utils-machine-at-point))))
8749abea
GM
551 (let ((buf (get-buffer-create (concat "*ftp [" host "]*"))))
552 (set-buffer buf)
8fb051f9 553 (ftp-mode)
8749abea
GM
554 (comint-exec buf (concat "ftp-" host) ftp-program nil
555 (if ftp-program-options
556 (append (list host) ftp-program-options)
557 (list host)))
8fb051f9 558 (pop-to-buffer buf)))
8749abea 559
8fb051f9 560(define-derived-mode ftp-mode comint-mode "FTP"
8749abea 561 "Major mode for interacting with the ftp program."
8749abea 562 (setq comint-prompt-regexp ftp-prompt-regexp)
8749abea 563 (setq comint-input-autoexpand t)
8fb051f9
MB
564 ;; Only add the password-prompting hook if it's not already in the
565 ;; global hook list. This stands a small chance of losing, if it's
566 ;; later removed from the global list (very small, since any
567 ;; password prompts will probably immediately follow the initial
568 ;; connection), but it's better than getting prompted twice for the
569 ;; same password.
570 (unless (memq 'comint-watch-for-password-prompt
571 (default-value 'comint-output-filter-functions))
572 (add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt
c2e6c8d1 573 nil t)))
8749abea 574
8749abea
GM
575;; Occasionally useful
576(define-key ftp-mode-map "\t" 'comint-dynamic-complete)
577
578(defun smbclient (host service)
579 "Connect to SERVICE on HOST via SMB."
ddb62bf1 580 (interactive
8749abea 581 (list
ddb62bf1 582 (read-from-minibuffer
8749abea
GM
583 "Connect to Host: " (net-utils-machine-at-point))
584 (read-from-minibuffer "SMB Service: ")))
8749abea
GM
585 (let* ((name (format "smbclient [%s\\%s]" host service))
586 (buf (get-buffer-create (concat "*" name "*")))
587 (service-name (concat "\\\\" host "\\" service)))
588 (set-buffer buf)
8fb051f9 589 (smbclient-mode)
8749abea
GM
590 (comint-exec buf name smbclient-program nil
591 (if smbclient-program-options
592 (append (list service-name) smbclient-program-options)
593 (list service-name)))
8fb051f9 594 (pop-to-buffer buf)))
8749abea
GM
595
596(defun smbclient-list-shares (host)
597 "List services on HOST."
ddb62bf1 598 (interactive
8749abea 599 (list
ddb62bf1 600 (read-from-minibuffer
c2e6c8d1 601 "Connect to Host: " (net-utils-machine-at-point))))
8749abea
GM
602 (let ((buf (get-buffer-create (format "*SMB Shares on %s*" host))))
603 (set-buffer buf)
8749abea 604 (smbclient-mode)
8fb051f9
MB
605 (comint-exec buf "smbclient-list-shares"
606 smbclient-program nil (list "-L" host))
607 (pop-to-buffer buf)))
ddb62bf1 608
8fb051f9 609(define-derived-mode smbclient-mode comint-mode "smbclient"
8749abea 610 "Major mode for interacting with the smbclient program."
8749abea 611 (setq comint-prompt-regexp smbclient-prompt-regexp)
8749abea 612 (setq comint-input-autoexpand t)
8fb051f9
MB
613 ;; Only add the password-prompting hook if it's not already in the
614 ;; global hook list. This stands a small chance of losing, if it's
615 ;; later removed from the global list (very small, since any
616 ;; password prompts will probably immediately follow the initial
617 ;; connection), but it's better than getting prompted twice for the
618 ;; same password.
619 (unless (memq 'comint-watch-for-password-prompt
620 (default-value 'comint-output-filter-functions))
621 (add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt
c2e6c8d1 622 nil t)))
8749abea 623
8749abea
GM
624
625;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
626;; Network Connections
627;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
628
629;; Full list is available at:
350ca08d 630;; http://www.iana.org/assignments/port-numbers
ddb62bf1 631(defvar network-connection-service-alist
8749abea
GM
632 (list
633 (cons 'echo 7)
634 (cons 'active-users 11)
635 (cons 'daytime 13)
636 (cons 'chargen 19)
637 (cons 'ftp 21)
638 (cons 'telnet 23)
639 (cons 'smtp 25)
640 (cons 'time 37)
641 (cons 'whois 43)
642 (cons 'gopher 70)
643 (cons 'finger 79)
644 (cons 'www 80)
645 (cons 'pop2 109)
646 (cons 'pop3 110)
647 (cons 'sun-rpc 111)
648 (cons 'nntp 119)
649 (cons 'ntp 123)
650 (cons 'netbios-name 137)
651 (cons 'netbios-data 139)
652 (cons 'irc 194)
653 (cons 'https 443)
c2e6c8d1 654 (cons 'rlogin 513))
8749abea 655 "Alist of services and associated TCP port numbers.
9d551c66
RS
656This list is not complete.")
657
20f28123
JB
658;; Workhorse routine
659(defun run-network-program (process-name host port &optional initial-string)
660 (let ((tcp-connection)
661 (buf))
662 (setq buf (get-buffer-create (concat "*" process-name "*")))
8749abea 663 (set-buffer buf)
ddb62bf1 664 (or
8749abea 665 (setq tcp-connection
20f28123
JB
666 (open-network-stream process-name buf host port))
667 (error "Could not open connection to %s" host))
8749abea
GM
668 (erase-buffer)
669 (set-marker (process-mark tcp-connection) (point-min))
670 (set-process-filter tcp-connection 'net-utils-remove-ctrl-m-filter)
20f28123 671 (and initial-string
ddb62bf1 672 (process-send-string tcp-connection
20f28123 673 (concat initial-string "\r\n")))
8749abea
GM
674 (display-buffer buf)))
675
676;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
677;; Simple protocols
678;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
679
086d5b87
GM
680(defcustom finger-X.500-host-regexps nil
681 "A list of regular expressions matching host names.
682If a host name passed to `finger' matches one of these regular
683expressions, it is assumed to be a host that doesn't accept
684queries of the form USER@HOST, and wants a query containing USER only."
685 :group 'net-utils
686 :type '(repeat regexp)
687 :version "21.1")
688
8749abea
GM
689;; Finger protocol
690;;;###autoload
691(defun finger (user host)
692 "Finger USER on HOST."
693 ;; One of those great interactive statements that's actually
694 ;; longer than the function call! The idea is that if the user
695 ;; uses a string like "pbreton@cs.umb.edu", we won't ask for the
696 ;; host name. If we don't see an "@", we'll prompt for the host.
697 (interactive
698 (let* ((answer (read-from-minibuffer "Finger User: "
699 (net-utils-url-at-point)))
700 (index (string-match (regexp-quote "@") answer)))
701 (if index
086d5b87
GM
702 (list (substring answer 0 index)
703 (substring answer (1+ index)))
704 (list answer
705 (read-from-minibuffer "At Host: "
706 (net-utils-machine-at-point))))))
707 (let* ((user-and-host (concat user "@" host))
708 (process-name (concat "Finger [" user-and-host "]"))
709 (regexps finger-X.500-host-regexps)
710 found)
ac8a1898
PB
711 (and regexps
712 (while (not (string-match (car regexps) host))
713 (setq regexps (cdr regexps)))
714 (when regexps
715 (setq user-and-host user)))
ddb62bf1
PB
716 (run-network-program
717 process-name
718 host
8749abea 719 (cdr (assoc 'finger network-connection-service-alist))
086d5b87 720 user-and-host)))
8749abea
GM
721
722(defcustom whois-server-name "rs.internic.net"
723 "Default host name for the whois service."
724 :group 'net-utils
c2e6c8d1 725 :type 'string)
8749abea
GM
726
727(defcustom whois-server-list
728 '(("whois.arin.net") ; Networks, ASN's, and related POC's (numbers)
729 ("rs.internic.net") ; domain related info
da888ddf 730 ("whois.publicinterestregistry.net")
8749abea
GM
731 ("whois.abuse.net")
732 ("whois.apnic.net")
733 ("nic.ddn.mil")
734 ("whois.nic.mil")
735 ("whois.nic.gov")
736 ("whois.ripe.net"))
737 "A list of whois servers that can be queried."
738 :group 'net-utils
739 :type '(repeat (list string)))
740
da888ddf
RF
741;; FIXME: modern whois clients include a much better tld <-> whois server
742;; list, Emacs should probably avoid specifying the server as the client
743;; will DTRT anyway... -rfr
8749abea
GM
744(defcustom whois-server-tld
745 '(("rs.internic.net" . "com")
da888ddf 746 ("whois.publicinterestregistry.net" . "org")
8749abea
GM
747 ("whois.ripe.net" . "be")
748 ("whois.ripe.net" . "de")
749 ("whois.ripe.net" . "dk")
750 ("whois.ripe.net" . "it")
751 ("whois.ripe.net" . "fi")
752 ("whois.ripe.net" . "fr")
753 ("whois.ripe.net" . "uk")
754 ("whois.apnic.net" . "au")
755 ("whois.apnic.net" . "ch")
756 ("whois.apnic.net" . "hk")
757 ("whois.apnic.net" . "jp")
758 ("whois.nic.gov" . "gov")
759 ("whois.nic.mil" . "mil"))
760 "Alist to map top level domains to whois servers."
761 :group 'net-utils
762 :type '(repeat (cons string string)))
763
764(defcustom whois-guess-server t
765 "If non-nil then whois will try to deduce the appropriate whois
766server from the query. If the query doesn't look like a domain or hostname
da888ddf 767then the server named by `whois-server-name' is used."
8749abea
GM
768 :group 'net-utils
769 :type 'boolean)
770
771(defun whois-get-tld (host)
772 "Return the top level domain of `host', or nil if it isn't a domain name."
773 (let ((i (1- (length host)))
774 (max-len (- (length host) 5)))
775 (while (not (or (= i max-len) (char-equal (aref host i) ?.)))
776 (setq i (1- i)))
777 (if (= i max-len)
778 nil
779 (substring host (1+ i)))))
780
781;; Whois protocol
782;;;###autoload
783(defun whois (arg search-string)
784 "Send SEARCH-STRING to server defined by the `whois-server-name' variable.
785If `whois-guess-server' is non-nil, then try to deduce the correct server
786from SEARCH-STRING. With argument, prompt for whois server."
787 (interactive "P\nsWhois: ")
788 (let* ((whois-apropos-host (if whois-guess-server
789 (rassoc (whois-get-tld search-string)
790 whois-server-tld)
791 nil))
792 (server-name (if whois-apropos-host
793 (car whois-apropos-host)
794 whois-server-name))
795 (host
796 (if arg
797 (completing-read "Whois server name: "
798 whois-server-list nil nil "whois.")
799 server-name)))
ddb62bf1 800 (run-network-program
8749abea
GM
801 "Whois"
802 host
803 (cdr (assoc 'whois network-connection-service-alist))
c2e6c8d1 804 search-string)))
8749abea
GM
805
806(defcustom whois-reverse-lookup-server "whois.arin.net"
807 "Server which provides inverse DNS mapping."
808 :group 'net-utils
c2e6c8d1 809 :type 'string)
8749abea
GM
810
811;;;###autoload
812(defun whois-reverse-lookup ()
813 (interactive)
814 (let ((whois-server-name whois-reverse-lookup-server))
815 (call-interactively 'whois)))
816
817;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
818;;; General Network connection
819;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
820
76540917 821;; Using a derived mode gives us keymaps, hooks, etc.
ddb62bf1 822(define-derived-mode
76540917 823 network-connection-mode comint-mode "Network-Connection"
c2e6c8d1 824 "Major mode for interacting with the network-connection program.")
76540917
PB
825
826(defun network-connection-mode-setup (host service)
96c01bd4
RS
827 (make-local-variable 'network-connection-host)
828 (setq network-connection-host host)
829 (make-local-variable 'network-connection-service)
ad21495f 830 (setq network-connection-service service))
76540917 831
8749abea
GM
832;;;###autoload
833(defun network-connection-to-service (host service)
834 "Open a network connection to SERVICE on HOST."
ddb62bf1 835 (interactive
8749abea
GM
836 (list
837 (read-from-minibuffer "Host: " (net-utils-machine-at-point))
ddb62bf1
PB
838 (completing-read "Service: "
839 (mapcar
840 (function
8749abea
GM
841 (lambda (elt)
842 (list (symbol-name (car elt)))))
843 network-connection-service-alist))))
ddb62bf1
PB
844 (network-connection
845 host
c2e6c8d1 846 (cdr (assoc (intern service) network-connection-service-alist))))
8749abea
GM
847
848;;;###autoload
849(defun network-connection (host port)
850 "Open a network connection to HOST on PORT."
851 (interactive "sHost: \nnPort: ")
852 (network-service-connection host (number-to-string port)))
853
854(defun network-service-connection (host service)
855 "Open a network connection to SERVICE on HOST."
c2e6c8d1
PJ
856 (let* ((process-name (concat "Network Connection [" host " " service "]"))
857 (portnum (string-to-number service))
858 (buf (get-buffer-create (concat "*" process-name "*"))))
8749abea 859 (or (zerop portnum) (setq service portnum))
ddb62bf1 860 (make-comint
8749abea
GM
861 process-name
862 (cons host service))
76540917
PB
863 (set-buffer buf)
864 (network-connection-mode)
865 (network-connection-mode-setup host service)
c2e6c8d1 866 (pop-to-buffer buf)))
8749abea 867
cbbe9a37
GM
868(defvar comint-input-ring)
869
ddb62bf1
PB
870(defun network-connection-reconnect ()
871 "Reconnect a network connection, preserving the old input ring."
872 (interactive)
873 (let ((proc (get-buffer-process (current-buffer)))
874 (old-comint-input-ring comint-input-ring)
875 (host network-connection-host)
c2e6c8d1 876 (service network-connection-service))
ddb62bf1
PB
877 (if (not (or (not proc)
878 (eq (process-status proc) 'closed)))
879 (message "Still connected")
880 (goto-char (point-max))
881 (insert (format "Reopening connection to %s\n" host))
882 (network-connection host
c2e6c8d1
PJ
883 (if (numberp service)
884 service
885 (cdr (assoc service network-connection-service-alist))))
ddb62bf1 886 (and old-comint-input-ring
c2e6c8d1 887 (setq comint-input-ring old-comint-input-ring)))))
ddb62bf1 888
8749abea
GM
889(provide 'net-utils)
890
891;;; net-utils.el ends here