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