1/*******************************************************************************
2September 1, 1996
3
4they said it couldn't be done...  THEY WERE WRONG.
5
6          Reverse DCC for ircii-epic by archon <archon@tamu.edu>
7
8The purpose of this script is to allow clients behind firewalls to dcc
9send.  If you and your intended recipient are both firewalled, use mail or
10ftp.
11
12Basically, instead of telling the recipient to connect to your machine
13where you will send them the file, you tell them to use their own
14own machine, then you send it.
15
16Both you and the recipient must be running this script for it to work.
17
18Thanks:
19  hop <jnelson@acronet.net> for writing EPIC, and for helping to get this
20  script working smoothly.
21
22
23Versions/Updates
24----------------
25 1.0a: it actually works for text files. wow, that wasn't so hard now was it?
26 1.0b: added uuencoding to work for binary files
27       fixed fexist() test in revsend
28 1.0c: changed port selection to be decided by the receiver
29 1.0d: minor fixes and cleaning up.  completed revclose.  added help.
30
31*******************************************************************************/
32
33set novice off
34
35alias ento {
36  @ function_return = encode($tolower($0))
37}
38
39alias revsend {
40  if ([$1]) {
41    @ rev.file = [$1]
42    userhost $0 -cmd if (index(. $4) > 0) {
43      @ rev.nick = ento($0)
44      @ rev.host[$rev.nick] = [$4]
45      if (fexist($rev.file) > 0) {
46        push sendqueue[$rev.nick] $rev.file
47        echo *** Sending reverse DCC request to $0
48        ^on ^ctcp_reply "$0 REVDCC REJECT $rev.file" {
49	  echo *** $0 has rejected reverse DCC SEND of $3
50	  @ rev.host[$rev.nick] = sendqueue[$rev.nick] = []
51	  ^on ctcp_reply -"$0 REVDCC REJECT $rev.file"
52	}
53        quote privmsg $0 :REVDCC SEND $rev.file\
54	@ rev.nick = rev.file = rev.seed = []
55      }{
56        echo *** Cannot access $W/$rev.file
57      }
58    }{
59      echo *** $0\: No such nick
60    }
61  }{
62    echo *** Usage: /revsend nick file
63  }
64}
65
66alias revget {
67  if ([$1]) {
68    @ rev.rnick = ento($0)
69    if (rev.fname[$rev.rnick]) {
70      echo *** Getting $1 from $0
71      @ listen($rev.port[$rev.rnick])
72      quote notice $0 :REVDCC GET $1 $rev.port[$rev.rnick]\
73      @ rev.rnick = []
74    }{
75      echo *** No reverse DCC SENDS pending from $0
76    }
77  }{
78    echo *** Usage: /revget nick file
79  }
80}
81
82alias receivefile {
83  @ rev.snick = [$3]
84  @ rev.file[$rev.snick] = [$0\.uu]
85  @ rev.lsocket = [$1]
86  @ rev.lport = [$2]
87  @ fd = open($rev.file[$rev.snick] W)
88  stack push on dcc_raw
89  ^on ^dcc_raw "$1 % D*" {
90#    exec -name decodefile$rev.file[$rev.snick] $3-
91    @ write($fd $3-)
92  }
93  ^on ^dcc_lost "$1 RAW *" {
94    echo *** Connection closed: File transfer complete... decoding.
95    ^on dcc_raw -"$rev.lsocket % D*"
96    ^on dcc_lost -"$0 RAW *"
97    dcc close raw_listen $rev.lport
98    @ close($fd)
99    ^on ^exec_exit "decodefile$rev.file[$rev.snick] *" {
100      echo *** Decoding complete
101      ^on exec_exit -"decodefile$rev.file[$rev.snick] *"
102      ^on dcc_raw -"% % N $rev.port[$rev.snick]"
103      @ unlink($rev.file[$rev.snick])
104      @ fd = sendnick = rev.file[$rev.snick] = rev.lsocket = rev.lport = rev.fname[$rev.snick] = rev.port[$rev.snick] = rev.snick = []
105    }
106    stack pop on dcc_raw
107    exec -name decodefile$rev.file[$rev.snick] uudecode $rev.file[$rev.snick]
108  }
109}
110
111alias revclose {
112  quote notice $0 :REVDCC REJECT $1\
113}
114
115on ^ctcp_reply "% REVDCC GET *" {
116  @ getnick = ento($0)
117  @ rev.sfile[$getnick] = [$3]
118  @ rev.sendport[$getnick] = [$4]
119  if (match($3 $sendqueue[$getnick])) {
120    ^on ^exec "sendfile$getnick *" {
121      dcc raw $rev.socket[$getnick] $rev.host[$getnick] $1-
122    }
123    ^on ^exec_exit "sendfile$getnick *" {
124      ^on exec -"sendfile$getnick *"
125      ^on exec_exit -"sendfile$getnick *"
126      ^on dcc_raw -"$rev.socket[$getnick] $rev.host[$getnick] C*"
127      ^on ctcp_reply -"$decode($getnick) REVDCC REJECT $rev.sfile[$getnick]"
128      timer 2 ^dcc close raw $rev.socket[$getnick]
129      echo *** Connection closed. File transfer complete.
130      @ rev.host[$getnick] = sendqueue[$getnick] = rev.sendport[$getnick] = rev.socket[$getnick] = rev.sfile[$getnick] = getnick = []
131    }
132    @ rev.socket[$getnick] = connect($rev.host[$getnick] $rev.sendport[$getnick])
133    echo *** Sending $3 to $0
134    ^exec -name sendfile$getnick uuencode $3 $3
135  }
136}
137
138on ^ctcp "% % REVDCC SEND *" {
139  @ sendnick = ento($0)
140  @ rev.fname[$sendnick] = [$4]
141  @ rev.seed = srand($time())
142  @ rev.port[$sendnick] = rand(10000) + 8000
143  ^on ^dcc_raw "% % N $rev.port[$sendnick]" {
144    receivefile $rev.fname[$sendnick] $0 $rev.port[$sendnick] $sendnick
145  }
146  echo *** Received reverse DCC SEND request from $0\: $4-
147  echo *** Use /revget $0 $4\ to get this file or /revclose $0 $4\ to cancel
148}
149
150alias revhelp {
151  echo _-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_
152  echo *** $center($word(0 $geom()) RevDCC.irc by archon v1.0d.epic)
153  echo *** Note: anything in <>'s is required. anything in []'s is optional
154  echo *** REVSEND <nick> <file>
155  echo ***      Sends <file> to <nick>
156  echo *** REVGET <nick> <file>
157  echo ***      Receives <file> from <nick>
158  echo *** REVCLOSE <nick> <file>
159  echo ***      Rejects send of <file> from <nick>
160  echo _-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_
161}
162
163echo [RevDCC] Reverse DCC v1.0d.epic by archon loaded!  Help: /revhelp
164
165/************************************************************
166to do:
167- flood protection
168- test for file existance (receiver)
169  - rename
170- uudecode from stdin
171************************************************************/
172