BSD 4_3_Net_2 development
[unix-history] / usr / src / contrib / isode / ftam-ftp / ftp_lib.c
CommitLineData
53102063
C
1/* ftp_lib.c - FTP subroutines */
2
3/*
4 * $Header: /f/osi/ftam-ftp/RCS/ftp_lib.c,v 7.2 91/02/22 09:23:29 mrose Interim $
5 *
6 *
7 * $Log: ftp_lib.c,v $
8 * Revision 7.2 91/02/22 09:23:29 mrose
9 * Interim 6.8
10 *
11 * Revision 7.1 90/12/23 18:39:51 mrose
12 * update
13 *
14 * Revision 7.0 89/11/23 21:55:06 mrose
15 * Release 6.0
16 *
17 */
18
19/*
20 * NOTICE
21 *
22 * The MITRE Corporation (hereafter MITRE) makes this software available
23 * on an "as is" basis. No guarantees, either explicit or implied, are
24 * given as to performance or suitability.
25 *
26 */
27
28/*
29 * Library interface routines. Design of routines is specific for
30 * FTAM.
31 */
32
33/*
34 * FTP User Program -- Command Routines.
35 */
36#include "config.h"
37#include <sys/param.h>
38#include <sys/stat.h>
39#include <sys/socket.h>
40
41#include <arpa/ftp.h>
42
43#include <signal.h>
44#include <stdio.h>
45#include <errno.h>
46#include <netdb.h>
47
48#include "ftp_var.h"
49#include "general.h"
50#include "logger.h"
51
52void advise ();
53#ifndef NULLCP
54#define NULLCP ((char *) 0)
55#endif
56
57#define FTP_PORT 21
58
59/* Virtual filesystem file types */
60
61#define VFS_UBF 0 /* offset to FTAM-3 */
62#define VFS_UTF 1 /* .. FTAM-1 */
63#define VFS_FDF 2 /* .. NBS-9 */
64
65#ifndef NOTOK
66#define NOTOK (-1)
67#define OK 0
68#define DONE 1
69#endif /* NOTOK */
70
71
72/*
73 * ftp_login: establish command connection with remote host
74 * then execute login process.
75 */
76int
77ftp_login(host,user,passwd,acct)
78char *host, *user, *passwd, *acct;
79{
80
81 if (connected) return NOTOK; /* already connected */
82
83 ftp_init(); /* initialize control state structures */
84 if (hookup(host,FTP_PORT) == NOTOK) return NOTOK;
85
86
87 /* execute login process */
88 if (login(user,passwd,acct) == NOTOK) return NOTOK;
89
90 return OK;
91}
92
93/*
94 * ftp_quit: send quit command and shutdown communications link.
95 */
96int
97ftp_quit()
98{
99
100 extern FILE *cout;
101 extern int data;
102 int n;
103
104 if (!connected) return OK;
105 n = command("QUIT");
106 (void) fclose(cout);
107 connected = 0;
108 data = -1;
109
110 if (n == 0 || n == COMPLETE) return OK;
111 return NOTOK;
112}
113
114/*
115 * ftp_abort: send abort command
116 */
117int
118ftp_abort()
119{
120int n;
121
122 if (!connected) return NOTOK;
123 n = command("ABOR");
124
125 if (n == COMPLETE) return OK;
126 return NOTOK;
127
128}
129
130/*
131 * ftp_exist: perform NLST command and count number of records in data
132 * stream. If 0 or reply code is failure, file does not exist. If 1
133 * or more and reply code is COMPLETE, file exists. ftp_directory is
134 * a global flag. It is set if more than 1 record in data stream and
135 * reply code is COMPLETE. Yes this is hokey but it works for all the
136 * test systems and is faster than trying a case sensitive, then case
137 * insensitive scan then falling back on record counts in the case of
138 * directories.
139 */
140int
141ftp_exist(filename)
142char *filename;
143{
144int n, count;
145int fd;
146FILE *fp, *fdopen();
147char lineX[BUFSIZ];
148
149 ftp_directory = 0;
150
151 if (!connected) return NOTOK;
152
153 /* set ascii transfer */
154 if (ftp_type(VFS_FDF) != OK) return NOTOK;
155
156 /* begin list transfer */
157 if ((fd = recvrequest("NLST",filename)) == NOTOK) return NOTOK;
158 if ((fp = fdopen(fd,"r")) == NULL){
159 (void)close(fd);
160 (void) getreply(0);
161 (void)sprintf(ftp_error,"Out of memory");
162 return NOTOK;
163 }
164
165 /* count number of records (lines) in data transfer */
166 for(count=0; fgets(lineX,BUFSIZ,fp)!=NULL; count++);
167 (void)fclose(fp);
168
169 /* transfer complete reply */
170 n = getreply(0);
171
172 if (n != COMPLETE) /* directory command not accepted */
173 return NOTOK;
174
175 /* if more than one record in reply, guess that it is a directory */
176 if (count > 1) {
177 ftp_directory = 1;
178 if (verbose)
179 advise (LLOG_DEBUG, NULLCP, "directory found");
180 }
181
182 /* if any records in reply, assume that file existed */
183 if (count) return OK;
184
185 return NOTOK;
186
187}
188
189/* Basicly set transfer type to ascii and issue NLST command
190 * and returning the socket descriptor for the data stream.
191 */
192int
193ftp_ls(dir)
194char *dir;
195{
196int fd;
197
198 if (!connected) return NOTOK;
199
200 /* set ascii transfer */
201 if (ftp_type(VFS_FDF) != OK) return NOTOK;
202
203 /* begin list transfer */
204 if ((fd = recvrequest("NLST",dir)) == NOTOK) return NOTOK;
205
206 return(fd);
207}
208int
209ftp_delete(file)
210char *file;
211{
212
213
214 if (!connected) return NOTOK;
215
216 /* send delete command, return OK if complete, NOTOK otherwise */
217 if (command("DELE %s", file) == COMPLETE) return OK;
218 /* Hummm, try directory delete */
219 if (command("XRMD %s", file) == COMPLETE) return OK;
220 /* No dice, return error */
221 return NOTOK;
222
223}
224
225int
226ftp_mkdir(dir)
227char *dir;
228{
229
230 if (!connected) return NOTOK;
231
232 /* send MKDIR command, return OK if complete, NOTOK otherwise */
233 if (command("XMKD %s", dir) == COMPLETE) return OK;
234 return NOTOK;
235
236}
237
238int
239ftp_rename(from,to)
240char *from, *to;
241{
242int n;
243
244 if (!connected) return NOTOK;
245
246 /* send RNFR command followed by RNTO if successful */
247 if ((n = command("RNFR %s",from)) == CONTINUE)
248 n = command("RNTO %s",to);
249 if (n == COMPLETE) return OK;
250 return NOTOK;
251
252}
253
254int
255ftp_write(file)
256char *file;
257{
258
259 if (!connected) return NOTOK;
260
261 return(sendrequest("STOR",file));
262}
263int
264ftp_append(file)
265char *file;
266{
267 if (!connected) return NOTOK;
268
269 return(sendrequest("APPE",file));
270}
271
272int
273ftp_read(file)
274char *file;
275{
276
277 if (!connected) return NOTOK;
278
279 return(recvrequest("RETR", file));
280}
281
282int
283ftp_type(modeX)
284int modeX;
285{
286int n;
287char cmd[10];
288
289 /* The current transfer type is stored in ``type''.
290 * The TYPE command is issued if the type changes.
291 * (this cuts down on the number of FTP transactions).
292 */
293 if (!connected) return NOTOK;
294 n = COMPLETE;
295
296 switch(modeX) {
297 /* unstructured binary file */
298 case VFS_UBF:
299 if (type == TYPE_L) break;
300 (void)sprintf(cmd, "TYPE L %s", bytename);
301 type = TYPE_L;
302 n = command(cmd,0);
303 break;
304 /* unstructured text file */
305 case VFS_UTF:
306 /* directory file */
307 case VFS_FDF:
308 default:
309 if (type == TYPE_A) break;
310 (void)sprintf(cmd, "TYPE A");
311 type = TYPE_A;
312 n = command(cmd,0);
313 }
314
315 if (n == COMPLETE) return OK;
316 return NOTOK;
317
318}
319
320int
321ftp_reply()
322{
323int n;
324
325 /* process an FTP response */
326
327 n = getreply(0);
328 if (n == COMPLETE) return OK;
329 return NOTOK;
330}
331
332int
333ftp_create(filename)
334char *filename;
335{
336int fd,n;
337
338 if (!connected) return NOTOK;
339
340 /* open file */
341 fd = sendrequest("STOR",filename);
342 if (fd == NOTOK) return NOTOK;
343
344 /* close file (create empty file) */
345 (void)close(fd);
346 n = getreply(0);
347 if (n == COMPLETE) return OK;
348 return NOTOK;
349
350}
351