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