;;; pure-pr-dcc-irchat.el --- interface for irchat-dcc process ;; Copyright (C) 2000 Project Pure / irchat-PJ Project. ;; Author: SHIMADA Mitsunobu <simm@pure.fan.gr.jp> ;; Keywords: PURE, IRC, process, DCC, irchat, dcc.c ;; $Id: pure-pr-dcc-irchat.el,v 1.1 2001/04/30 15:12:36 simm Exp $ ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; PURE means "Primitive Universal Relay-chat Environment" ;;; Code: (require 'pure-pr-filter) (require 'pure-irc-dcc-info) (defvar pure-pr-dcc-irchat-program "dcc" "Filename of DCC program of irchat.") (defvar pure-pr-dcc-irchat-support-resume 'unknown) ;; start DCC CHAT server process (defun pure-pr-dcc-irchat-start-chat-server (dinfo &optional resume) "Start dcc process of irchat: DCC CHAT listen" (let* ((host (pure-irc-dcc-info-get-host dinfo)) (port (pure-irc-dcc-info-get-port dinfo)) (proc (cond (host (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "chat" "listen" port host)) (port (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "chat" "listen" port)) (t (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "chat" "listen"))))) (if proc (pure-pr-filter-set-filter proc 'pure-pr-dcc-irchat-chat-parser)) proc)) ;; start DCC CHAT client process (defun pure-pr-dcc-irchat-start-chat-client (dinfo &optional resume) "Start dcc process of irchat: DCC CHAT connect" (let* ((host (pure-irc-dcc-info-get-host dinfo)) (port (pure-irc-dcc-info-get-port dinfo)) (proc (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "chat" "connect" host port))) (if proc (pure-pr-filter-set-filter proc 'pure-pr-dcc-irchat-chat-parser)) proc)) ;; start DCC SEND server process (defun pure-pr-dcc-irchat-start-file-server (dinfo &optional resume) "Start dcc process of irchat: DCC file server listen" (let* ((host (pure-irc-dcc-info-get-host dinfo)) (port (pure-irc-dcc-info-get-port dinfo)) (file (pure-irc-dcc-info-get-file dinfo)) (proc (cond (host (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "file" "send" file port host)) (port (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "file" "send" file port)) (t (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "file" "send" file))))) (if proc (pure-pr-filter-set-filter proc 'pure-pr-dcc-irchat-file-parser)) proc)) ;; start DCC FILE get process (defun pure-pr-dcc-irchat-start-file-client (dinfo &optional resume) "Start dcc process of irchat: DCC CHAT connect" (let* ((host (pure-irc-dcc-info-get-host dinfo)) (port (pure-irc-dcc-info-get-port dinfo)) (file (pure-irc-dcc-info-get-file dinfo)) (size (pure-irc-dcc-info-get-size dinfo)) (proc (start-process pure-pr-dcc-irchat-program (pure-irc-dcc-info-get-buffer dinfo) pure-pr-dcc-irchat-program "file" (if resume "rget" "get") host port size file))) (if proc (pure-pr-filter-set-filter proc 'pure-pr-dcc-irchat-file-parser)) proc)) ;; ;; DCC RESUME operation ;; ;; check whether DCC RESUME enable (defun pure-pr-dcc-irchat-resumep (dinfo) "Check dcc process supports DCC RESUME feature" (if (eq 'unknown pure-pr-dcc-irchat-support-resume) (let (path rest) (if (file-executable-p pure-pr-dcc-irchat-program) (setq path pure-pr-dcc-irchat-program) (setq rest exec-path) (while rest (setq path (expand-file-name pure-pr-dcc-irchat-program (car rest)) rest (cdr rest)) (if (file-executable-p path) (setq rest nil)))) (if path (setq pure-pr-dcc-irchat-support-resume (= 0 (call-process pure-pr-dcc-irchat-program nil nil nil "check" "resume"))))) pure-pr-dcc-irchat-support-resume)) (defun pure-pr-dcc-irchat-check-resume (&rest args) "Check dcc process supports DCC RESUME feature manually" (interactive) (setq pure-pr-dcc-irchat-support-resume 'unknown) (pure-pr-dcc-irchat-resumep nil)) ;; Accept DCC RESUME request (defun pure-pr-dcc-irchat-resume-accept (dinfo) "Accept DCC RESUME request" (process-send-string (pure-irc-dcc-info-get-proc dinfo) (format "DCC RESUME %s %s %s\n" (pure-irc-dcc-info-get-file dinfo) (pure-irc-dcc-info-get-port dinfo) (pure-irc-dcc-info-get-xpos dinfo)))) ;; Start DCC RESUME client process (defun pure-pr-dcc-irchat-resume-start (dinfo) "Start DCC RESUME client process" (process-send-string (pure-irc-dcc-info-get-proc dinfo) (format "DCC ACCEPT %s %s %s\n" (pure-irc-dcc-info-get-file dinfo) (pure-irc-dcc-info-get-port dinfo) (pure-irc-dcc-info-get-xpos dinfo)))) ;; ;; Parser functions for dcc.c ;; (defun pure-pr-dcc-irchat-file-parser (proc) "DCC parser function for DCC SEND/get." (cond ((looking-at "DCC SEND \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)") (pure-irc-dcc-info-send-server-info pure-irc-dcc-info (buffer-substring (match-beginning 1) (match-end 1)) (buffer-substring (match-beginning 2) (match-end 2)) (buffer-substring (match-beginning 3) (match-end 3)))) ((looking-at "DCC RESUME \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)") (if (not (pure-pr-dcc-irchat-resumep pure-irc-dcc-info)) (message "DCC WARNING: not support DCC RESUME") (pure-irc-dcc-info-put-xpos pure-irc-dcc-info (buffer-substring (match-beginning 3) (match-end 3))) (pure-irc-dcc-info-resume-request pure-irc-dcc-info))) ((looking-at "DCC ACCEPT \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)") (if (not (pure-pr-dcc-irchat-resumep pure-irc-dcc-info)) (message "DCC WARNING: not support DCC RESUME") (pure-irc-dcc-info-put-xpos pure-irc-dcc-info (buffer-substring (match-beginning 3) (match-end 3))) (pure-irc-dcc-info-resume-accept pure-irc-dcc-info))) ((looking-at "DCC SENDING") (pure-irc-dcc-info-put-status pure-irc-dcc-info 'server) (funcall pure-irc-dcc-log-interface "DCC SEND to %s established (%s, %s bytes)." (pure-irc-dcc-info-get-nick pure-irc-dcc-info) (pure-irc-dcc-info-get-file pure-irc-dcc-info) (pure-irc-dcc-info-get-size pure-irc-dcc-info))) ((looking-at "DCC GETTING") (pure-irc-dcc-info-put-status pure-irc-dcc-info 'client) (funcall pure-irc-dcc-log-interface "DCC GET from %s established (%s, %s bytes)." (pure-irc-dcc-info-get-nick pure-irc-dcc-info) (pure-irc-dcc-info-get-file pure-irc-dcc-info) (pure-irc-dcc-info-get-size pure-irc-dcc-info))) ((looking-at "DCC REPORT ") (message "DCC REPORT: %s" (buffer-substring (match-end 0) end))) ((looking-at "DCC WARNING Not Support Send Resume") (message "DCC WARNING: not support send resume")) (t (pure-pr-dcc-irchat-error-parser proc)))) (defun pure-pr-dcc-irchat-chat-parser (proc) "DCC parser function for DCC CHAT." (cond ((looking-at "DCC CHAT \\([^ ]+\\) \\([^ ]+\\)") (let ((pure-pr-my-addr (buffer-substring (match-beginning 1) (match-end 1))) (pure-pr-my-port (buffer-substring (match-beginning 2) (match-end 2)))) (pure-irc-dcc-chat-listen))) ((looking-at "DCC CHATTING") (pure-irc-dcc-chat-connect proc (if (eq 'connect (pure-irc-dcc-info-get-status pure-irc-dcc-info)) 'client 'server)) (pure-pr-filter-set-parser proc 'pure-irc-dcc-chat-parser)) (t (pure-pr-dcc-irchat-error-parser proc)))) (defun pure-pr-dcc-irchat-error-parser (proc) "DCC parser function for errors." (cond ((looking-at "DCC WARNINIG ") (message "DCC WARNINIG: %s" (buffer-substring (match-end 0) (point-max)))) ((looking-at "DCC WARN ") (message "DCC WARNINIG: %s" (buffer-substring (match-end 0) (point-max)))) ((looking-at "DCC ERROR1 ") (funcall pure-irc-dcc-log-interface "DCC ERROR: %s" (buffer-substring (match-end 0) (point-max))) (pure-ds-add-list pure-irc-dcc-info pure-irc-dcc-offer-list)) ((looking-at "DCC ERROR ") (funcall pure-irc-dcc-log-interface "DCC ERROR: %s" (buffer-substring (match-end 0) (point-max)))) (t ; unknown (funcall pure-irc-dcc-log-interface "DCC FATAL ERROR: %s" (buffer-substring (point-min) (point-max)))))) ;; That's all (provide 'pure-pr-dcc-irchat) ;;; pure-pr-dcc-irchat.el ends here