ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/c++/socket++-1.10/ftp.C
Revision: 1.2
Committed: Mon Jun 10 14:10:44 2002 UTC (22 years, 3 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
State: FILE REMOVED
Error occurred while calculating annotation data.
Log Message:
Tidy up of files. These are all old things that are not only no longer used
but are also probably useless to anyone other than us. This saves checking
them out all the time, and makes the "cms/source" tree contain only current
stuff. They'll still exist in the attic's though :)

File Contents

# Content
1 // ftp.h
2 // Copyright (C) 1992-1995 Gnanasekaran Swaminathan <gs4t@virginia.edu>
3 //
4 // Permission is granted to use at your own risk and distribute this software
5 // in source and binary forms provided the above copyright
6 // notice and this paragraph are preserved on all copies.
7 // This software is provided "as is" with no express or implied warranty.
8 //
9 // Version: 17Oct95 1.10
10
11 #include <config.h>
12
13 #include <ftp.h>
14 #include <fstream.h>
15 #include <Fork.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <stdio.h> // for sprintf
21 #include <errno.h>
22
23 #if defined (__osf__) && defined (__DECCXX)
24 extern "C" {
25 # include <netdb.h>
26 }
27 #else
28 # include <netdb.h>
29 #endif
30
31 char reptype [][8] = {
32 "A N",
33 "A T",
34 "A C",
35 "E N",
36 "E T",
37 "E C",
38 "I",
39 "L "
40 };
41
42 char filestru [][8] = {
43 "F",
44 "R",
45 "P"
46 };
47
48 char transmode [][8] = {
49 "S",
50 "B",
51 "C"
52 };
53
54 // ftpdata waits on a port at the local machine.
55 // When a connection is made, it receives a file from remote
56 // host if the ostream o is set, or it sends a file to the remote
57 // host if the istream i is set.
58 ftp::replycodea ftp::ftpbuf::ftpdata (int portno, istream* i, ostream* o,
59 const char* cmd, const char* arg)
60 {
61 sockinetbuf sb (sockbuf::sock_stream, 0);
62
63 if (sb.bind_until_success (portno)) {
64 sock_error ("ftpdata: ", "bind_until_success failed");
65 exit (1);
66 }
67
68 useraddr (sb.localaddr ());
69
70 sb.listen (1);
71
72 if (send_cmd (cmd, arg) >= ftp::rca_error)
73 return ftp::rca_error;
74
75 sockbuf c = sb.accept ();
76
77 if (o) {
78 // read data from c and put it in o
79 char buf [1024];
80 int rdsz;
81
82 while ((rdsz = c.sys_read (buf, 1024)) != EOF)
83 o->write (buf, rdsz);
84 } else if (i) {
85 // read data from i and send it to c
86 char buf [1024];
87 int rdsz;
88 streambuf* rb = i->rdbuf ();
89
90 while ((rdsz = rb->xsgetn (buf, 1024)) > 0) {
91 int wrsz = c.sys_write (buf, rdsz);
92 if (rdsz != wrsz)
93 cerr << "write error\n";
94 }
95
96 c.close (); // this close is needed. Otherwise, c will not send
97 // a response.
98 }
99
100 return get_response ();
101 }
102
103 ftp::replycodea ftp::ftpbuf::get_response ()
104 // get all the response that one can get and send all of them to o
105 {
106 // if o is 0, then we trash data.
107 int firstline = 1;
108 while (underflow () != EOF) {
109 int n = in_avail ();
110 if (n < 5)
111 continue;
112
113 // data is of this form: 221 repsonse <CRLF> or 221-response <CRLF>
114 char* q = gptr ();
115 char* p = q;
116
117 // zap upto <CRLF>
118 int i = 0;
119 for (i = 2; i <= n; i++, p++)
120 if (*p == '\r' && *(p+1) == '\n') {
121 break;
122 }
123 if (o)
124 o->write (q, i);
125 gbump (i);
126
127 if (firstline) {
128 strncpy (replycode, q, 3);
129 replycode [3] = ' ';
130 if (q [3] == ' ')
131 break;
132 firstline = 0;
133 } else if (strncmp (q, replycode, 4) == 0)
134 break;
135 }
136
137 return (replycodea) replycode [0];
138 }
139
140 ftp::replycodea ftp::ftpbuf::send_cmd (const char* cmd,
141 const char* arg)
142 {
143 xsputn (cmd, ::strlen (cmd));
144 if (arg) {
145 xsputn (" ", 1);
146 xsputn (arg, ::strlen (arg));
147 }
148 xsputn ("\r\n", 2);
149 flush_output ();
150
151 return get_response ();
152 }
153
154 ftp::ftp (ostream* out)
155 : ios (0)
156 {
157 ios::init (new ftpbuf (out));
158 }
159
160 ftp::ftpbuf::ftpbuf (ostream* out)
161 : protocol::protocolbuf (protocol::tcp),
162 o (out)
163 {
164 replycode [4] = 0;
165 }
166
167 void ftp::ftpbuf::serve_clients (int portno)
168 // right now no server ftp class cannot be used as a server
169 {}
170
171 ftp::replycodea ftp::ftpbuf::cd (const char* dir)
172 {
173 return send_cmd ("CWD", dir);
174 }
175
176 ftp::replycodea ftp::ftpbuf::useraddr (sockinetaddr sa)
177 {
178 if (sa.sin_addr.s_addr == 0) {
179 // local host
180 char hostname [64];
181 if (::gethostname (hostname, 63) == -1) {
182 perror ("ftpbuf::useraddr");
183 return ftp::rca_error;
184 }
185
186 hostent* hp = gethostbyname (hostname);
187 if (hp == 0) {
188 sock_error ("ftpbuf: ", "gethostbyname");
189 return ftp::rca_error;
190 }
191
192 memcpy (&sa.sin_addr, hp->h_addr, hp->h_length);
193 }
194
195 struct in_addr ina = sa.sin_addr;
196 int portno = ntohs(sa.sin_port);
197 char* ina_p = inet_ntoa (ina);
198 char addr [80];
199
200 char* p = 0;
201 strcpy (addr, ina_p);
202 while (p = strchr (addr, '.'))
203 *p = ',';
204
205 int hi_portno = portno >> 8;
206 int lo_portno = portno & 0xff;
207
208 sprintf (addr + strlen (addr), ",%d,%d", hi_portno, lo_portno);
209
210 return send_cmd ("PORT", addr);
211 }
212
213 ftp::replycodea ftp::ftpbuf::useraddr (const char* hostname, int portno)
214 {
215 return useraddr (sockinetaddr (hostname, portno));
216 }
217
218 ftp::replycodea ftp::ftpbuf::server_port (int portno)
219 {
220 int hi_portno = portno >> 8;
221 int lo_portno = portno & 0xff;
222 char port [80];
223
224 sprintf (port, "%d,%d", hi_portno, lo_portno);
225
226 return send_cmd ("PASV", port);
227 }
228
229 ftp::replycodea ftp::ftpbuf::rep_type (ftp::reptype rt)
230 {
231 return send_cmd ("TYPE", ::reptype [int(rt)]);
232 }
233
234 ftp::replycodea ftp::ftpbuf::file_stru (ftp::filestru fs)
235 {
236 return send_cmd ("STRU", ::filestru [int(fs)]);
237 }
238
239 ftp::replycodea ftp::ftpbuf::trans_mode (ftp::transmode tm)
240 {
241 return send_cmd ("STRU", ::transmode [int(tm)]);
242 }
243
244 ftp::replycodea ftp::ftpbuf::getfile (const char* rpath, const char* lpath)
245 {
246 if (lpath == 0)
247 lpath = rpath;
248
249 if (rpath == 0)
250 list ();
251
252 ofstream f (lpath);
253 return ftpdata (10000, 0, &f, "RETR", rpath);
254 }
255
256 ftp::replycodea ftp::ftpbuf::list (const char* rpath, int justnames)
257 {
258 if (justnames)
259 return ftpdata (10000, 0, o, "NLST", rpath);
260 else
261 return ftpdata (10000, 0, o, "LIST", rpath);
262 }
263
264 ftp::replycodea ftp::ftpbuf::putfile (const char* lpath, const char* rpath)
265 {
266 if (rpath == 0)
267 rpath = lpath;
268
269 if (lpath == 0)
270 return ftp::rca_error;
271
272 ifstream f(lpath);
273 return ftpdata (10000, &f, 0, "STOR", rpath);
274 }
275
276 ftp::replycodea ftp::ftpbuf::putfile (const char* lpath)
277 {
278 if (lpath == 0)
279 return ftp::rca_error;
280
281 ifstream f(lpath);
282 return ftpdata (10000, &f, 0, "STOU", lpath);
283 }
284
285 ftp::replycodea ftp::ftpbuf::append (const char* lpath, const char* rpath)
286 {
287 if (lpath == 0)
288 return ftp::rca_error;
289
290 if (rpath == 0)
291 rpath = lpath;
292
293 ifstream f(lpath);
294 return ftpdata (10000, &f, 0, "APPE", 0);
295 }
296
297 ftp::replycodea ftp::ftpbuf::allocate (int numbytes)
298 {
299 char b[32];
300 sprintf (b, "%d", numbytes);
301 return send_cmd ("ALLO", b);
302 }
303
304 ftp::replycodea ftp::ftpbuf::restart (int marker)
305 {
306 char b[32];
307 sprintf (b, "%d", marker);
308 return send_cmd ("REST", b);
309 }
310
311 ftp::replycodea ftp::ftpbuf::rename (const char* rpath, const char* newrpath)
312 {
313 if (rpath == 0 || newrpath == 0)
314 return ftp::rca_error;
315
316 if (send_cmd ("RNFR", rpath) >= ftp::rca_error)
317 return rca_error;
318
319 return send_cmd ("RNTO", newrpath);
320 }
321
322 ftp::replycodea ftp::ftpbuf::rmfile (const char* rpath)
323 {
324 return send_cmd ("DELE", rpath);
325 }
326
327 ftp::replycodea ftp::ftpbuf::rmdir (const char* rpath)
328 {
329 return send_cmd ("RMD", rpath);
330 }
331
332 ftp::replycodea ftp::ftpbuf::mkdir (const char* rpath)
333 {
334 return send_cmd ("MKD", rpath);
335 }
336