net-utils.el 27 KB

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