(U+63B2): Add `shinjigen@rev' into `<-simplified@JP/Jouyou*sources'.
[chise/xemacs-chise.git.1] / netinstall / nio-ftp.cc
1 /*
2  * Copyright (c) 2000, Red Hat, Inc.
3  *
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  *
9  *     A copy of the GNU General Public License can be found at
10  *     http://www.gnu.org/
11  *
12  * Written by DJ Delorie <dj@cygnus.com>
13  *
14  */
15
16 /* This file is responsible for implementing all direct FTP protocol
17    channels.  It is intentionally simplistic. */
18
19 #include "win32.h"
20 #include "winsock.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ctype.h>
24
25 #include "resource.h"
26 #include "state.h"
27 #include "simpsock.h"
28 #include "log.h"
29
30 #include "netio.h"
31 #include "nio-ftp.h"
32
33 static SimpleSocket *cmd = 0;
34 static char *cmd_host = 0;
35 static int cmd_port = 0;
36
37 static char *last_line;
38
39 static int
40 ftp_line (SimpleSocket *s)
41 {
42   do {
43     last_line = s->gets ();
44     log (LOG_BABBLE, "ftp > %s", last_line);
45   } while (last_line && (!isdigit (last_line[0]) || last_line[3] != ' '));
46   return atoi (last_line ?: "0");
47 }
48
49 NetIO_FTP::NetIO_FTP (char *Purl)
50   : NetIO (Purl)
51 {
52   s = 0;
53   int code;
54
55   if (port == 0)
56     port = 21;
57
58   if (cmd_host && strcmp (host, cmd_host) != 0 || port != cmd_port)
59     {
60       if (cmd)
61         cmd->printf ("QUIT\r\n");
62       delete cmd;
63       free (cmd_host);
64       cmd = 0;
65       cmd_host = 0;
66     }
67
68   if (cmd == 0)
69     {
70       SimpleSocket *c = new SimpleSocket (host, port);
71       code = ftp_line (c);
72       c->printf ("USER anonymous\r\n");
73       code = ftp_line (c);
74       if (code == 331)
75         {
76           c->printf ("PASS xemacs-setup@\r\n");
77           code = ftp_line (c);
78         }
79
80       if (code < 200 || code >= 300)
81         {
82           delete c;
83           return;
84         }
85
86       cmd = c;
87       cmd_host = _strdup (host);
88       cmd_port = port;
89
90       cmd->printf ("TYPE I\r\n");
91       code = ftp_line (cmd);
92     }
93
94   cmd->printf ("PASV\r\n");
95   do {
96     code = ftp_line (cmd);
97   } while (code == 226); /* previous RETR */
98   if (code != 227)
99     return;
100
101   char *paren = strchr (last_line, '(');
102   if (!paren)
103     return;
104
105   int i1, i2, i3, i4, p1, p2;
106   sscanf (paren+1, "%d,%d,%d,%d,%d,%d", &i1, &i2, &i3, &i4, &p1, &p2);
107   char tmp[20];
108   sprintf (tmp, "%d.%d.%d.%d", i1, i2, i3, i4);
109   s = new SimpleSocket (tmp, p1*256 + p2);
110
111   cmd->printf ("RETR %s\r\n", path);
112   code = ftp_line (cmd);
113   if (code != 150)
114     {
115       delete s;
116       s = 0;
117       return;
118     }
119 }
120
121 NetIO_FTP::~NetIO_FTP ()
122 {
123   if (s)
124     delete s;
125 }
126
127 int
128 NetIO_FTP::ok ()
129 {
130   if (s)
131     return 1;
132   return 0;
133 }
134
135 int
136 NetIO_FTP::read (char *buf, int nbytes)
137 {
138   if (!s)
139     return 0;
140   return s->read (buf, nbytes);
141 }