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, 5 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
State: FILE REMOVED
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

# User Rev Content
1 ab11 1.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