opendir change: refinement
[minix.git] / commands / ftp101 / ftp.c
blobc968f6e604f123f8ca0ca154485e4a9031de360c
1 /* ftp.c Copyright 1992-2000 by Michael Temari All Rights Reserved
3 * ftp An ftp client program for use with TNET.
5 * Usage: ftp [host]
7 * Version: 0.10 06/21/92 (pre-release not yet completed)
8 * 0.20 07/01/92
9 * 0.30 01/15/96 (Minix 1.7.1 initial release)
10 * 0.40 08/27/96
11 * 0.50 03/08/00
12 * 1.00 12/12/03 (added ver command)
13 * 1.01 02/07/05
15 * Author: Michael Temari, <Michael@TemWare.Com>
18 #include <sys/types.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <string.h>
23 #include <unistd.h>
25 #include "ftp.h"
26 #include "local.h"
27 #include "file.h"
28 #include "other.h"
29 #include "net.h"
31 char *FtpVersion = "1.01 02/07/05";
33 int linkopen;
34 int loggedin;
35 int type;
36 int format;
37 int mode;
38 int structure;
39 int passive;
40 int atty;
42 int cmdargc;
43 char *cmdargv[NUMARGS];
45 int printreply = 1;
46 char reply[1024];
48 #ifdef __NBSD_LIBC
49 /* Already declared in stdio.h */
50 #define getline ftp_getline
51 #endif
53 static void makeargs(char *buff);
54 int DOver(void);
55 int DOhelp(void);
56 static int getline(char *line, int len);
57 int main(int argc, char *argv[]);
60 static void makeargs(buff)
61 char *buff;
63 int i;
64 char *p;
66 for(i = 0; i < NUMARGS; i++)
67 cmdargv[i] = (char *)0;
69 p = buff + strlen(buff) - 1;
70 while(p >= buff)
71 if(*p == '\r' || *p == '\n' || isspace(*p))
72 *p-- = '\0';
73 else
74 break;
76 p = buff;
77 cmdargc = 0;
78 while(cmdargc < NUMARGS) {
79 while(*p && isspace(*p))
80 p++;
81 if(*p == '\0')
82 break;
83 cmdargv[cmdargc++] = p;
84 while(*p && !isspace(*p)) {
85 if(cmdargc == 1)
86 *p = tolower(*p);
87 p++;
89 if(*p == '\0')
90 break;
91 *p = '\0';
92 p++;
96 int readline(prompt, buff, len)
97 char *prompt;
98 char *buff;
99 int len;
101 char *p;
103 printf(prompt); fflush(stdout);
105 if(fgets(buff, len, stdin) == (char *)NULL) {
106 printf("\nEnd of file on input!\n");
107 return(-1);
110 p = buff + strlen(buff) - 1;
111 while(p >= buff)
112 if(*p == '\r' || *p == '\n' || isspace(*p))
113 *p-- = '\0';
114 else
115 break;
117 if(!atty) {
118 printf("%s\n", buff);
119 fflush(stdout);
122 return(0);
125 static int getline(line, len)
126 char *line;
127 int len;
129 int s;
130 int gotcr;
132 /* leave room for at end for null */
133 len--;
135 /* got to be able to put in at least 1 character */
136 if(len < 1)
137 return(-1);
139 gotcr = 0;
140 while(len-- > 0) {
141 s = read(ftpcomm_fd, line, 1);
142 if(s != 1)
143 return(-1);
144 if(*line == '\n')
145 break;
146 gotcr = (*line == '\r');
147 line++;
149 if(gotcr)
150 --line;
152 *line = '\0';
154 return(0);
157 int DOgetreply()
159 int firsttime;
160 int s;
161 char code[4];
163 do {
164 firsttime = 1;
165 do {
166 if((s = getline(reply, sizeof(reply))) < 0)
167 return(s);
168 if(printreply) {
169 printf("%s\n", reply);
170 fflush(stdout);
172 if(firsttime) {
173 firsttime = 0;
174 strncpy(code, reply, 3);
175 code[3] = '\0';
177 } while(strncmp(reply, code, 3) || reply[3] == '-');
178 s = atoi(code);
179 } while(s < 200 && s != 125 && s != 150);
181 return(s);
184 int DOcmdcheck()
186 if(!linkopen) {
187 printf("You must \"OPEN\" a connection first.\n");
188 return(1);
191 if(!loggedin) {
192 printf("You must login first.\n");
193 return(1);
196 return(0);
199 int DOcommand(ftpcommand, ftparg)
200 char *ftpcommand;
201 char *ftparg;
203 int s;
204 #if 1
205 static char ss[64];
206 if(*ftparg)
207 sprintf(ss, "%s %s\r\n", ftpcommand, ftparg);
208 else
209 sprintf(ss, "%s\r\n", ftpcommand);
211 s = write(ftpcomm_fd, ss, strlen(ss));
212 if(s != strlen(ss))
213 return(-1);
215 #else
216 s = write(ftpcomm_fd, ftpcommand, strlen(ftpcommand));
217 if(s != strlen(ftpcommand))
218 return(-1);
220 if(*ftparg) {
221 s = write(ftpcomm_fd, " ", 1);
222 if(s != 1)
223 return(-1);
225 s = write(ftpcomm_fd, ftparg, strlen(ftparg));
226 if(s != strlen(ftparg))
227 return(-1);
230 s = write(ftpcomm_fd, "\r\n", 2);
231 if(s != 2)
232 return(-1);
233 #endif
235 return(DOgetreply());
238 int DOver()
240 printf("FTP Version %s\n", FtpVersion);
241 return(0);
244 int DOhelp()
246 char junk[10];
248 printf("Command: Description\n");
249 printf("! Escape to a shell\n");
250 printf("append Append a file to remote host\n");
251 printf("ascii Set file transfer type to ascii\n");
252 printf("binary Set file transfer type to binary\n");
253 printf("block Set file transfer mode to block\n");
254 printf("bye Close connection and exit\n");
255 printf("cd Change directory on remote host\n");
256 printf("close Close connection\n");
257 printf("clone Clone a file\n");
258 printf("del Remove file on remote host\n");
259 printf("dir Display long form remote host directory listing\n");
260 printf("exit Close connection and exit\n");
261 printf("get Retrieve a file from remote host\n");
262 printf("help Display this text\n");
264 if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
265 return(-1);
267 printf("lcd Change directory on local host\n");
268 printf("ldir Display long form local host directory listing\n");
269 printf("lls Display local host directory listing\n");
270 printf("lmkdir Create directory on local host\n");
271 printf("lpwd Display current directory on local host\n");
272 printf("lrmdir Remove directory on local host\n");
273 printf("ls Display remote host directory listing\n");
274 printf("mget Retrieve multiple files from remote host\n");
275 printf("mkdir Create directory on remote host\n");
276 printf("mod Get file modification time\n");
277 printf("mput Send multiple files to remote host\n");
278 printf("noop Send the ftp NOOP command\n");
280 if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
281 return(-1);
283 printf("open Open connection to remote host\n");
284 printf("pass Enter remote user password\n");
285 printf("passive Toggle passive mode\n");
286 printf("put Send a file to remote host\n");
287 printf("putu Send a file to remote host(unique)\n");
288 printf("pwd Display current directory on remote host\n");
289 printf("quit Close connection and exit\n");
290 printf("quote Send raw ftp command to remote host\n");
291 printf("reget Restart a partial file retrieve from remote host\n");
292 printf("remotehelp Display ftp commands implemented on remote host\n");
293 printf("reput Restart a partial file send to remote host\n");
294 printf("rm Remove file on remote host\n");
295 printf("rmdir Remove directory on remote host\n");
297 if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
298 return(-1);
300 printf("site Send a site specific command\n");
301 printf("size Get file size information\n");
302 printf("status Get connection/file status information\n");
303 printf("stream Set file transfer mode to stream\n");
304 printf("system Get remote system type information\n");
305 printf("user Enter remote user information\n");
306 printf("ver Display client version information\n");
308 return(0);
311 struct commands {
312 char *name;
313 int(*func) (void);
316 static struct commands commands[] = {
317 "!", DOlshell,
318 "append", DOappe,
319 "ascii", DOascii,
320 "binary", DObinary,
321 "block", DOblock,
322 "bye", DOquit,
323 "cd", DOcd,
324 "close", DOclose,
325 "clone", DOclone,
326 "del", DOdelete,
327 "dir", DOlist,
328 "exit", DOquit,
329 "get", DOretr,
330 "help", DOhelp,
331 "lcd", DOlcd,
332 "ldir", DOllist,
333 "lls", DOlnlst,
334 "lmkdir", DOlmkdir,
335 "lpwd", DOlpwd,
336 "lrmdir", DOlrmdir,
337 "ls", DOnlst,
338 "mget", DOMretr,
339 "mkdir", DOmkdir,
340 "mod", DOmdtm,
341 "mput", DOMstor,
342 "noop", DOnoop,
343 "open", DOopen,
344 "pass", DOpass,
345 "passive", DOpassive,
346 "put", DOstor,
347 "putu", DOstou,
348 "pwd", DOpwd,
349 "quit", DOquit,
350 "quote", DOquote,
351 "reget", DOrretr,
352 "remotehelp", DOremotehelp,
353 "reput", DOrstor,
354 "rm", DOdelete,
355 "rmdir", DOrmdir,
356 "site", DOsite,
357 "size", DOsize,
358 "status", DOstat,
359 "stream", DOstream,
360 "system", DOsyst,
361 "user", DOuser,
362 "ver", DOver,
363 "", (int (*)())0
366 int main(argc, argv)
367 int argc;
368 char *argv[];
370 int s;
371 struct commands *cmd;
372 static char buffer[128];
374 if(NETinit())
375 return(-1);
377 FTPinit();
379 s = 0;
381 if(argc > 1) {
382 sprintf(buffer, "open %s ", argv[1]);
383 makeargs(buffer);
384 s = DOopen();
385 if(atty && s > 0) {
386 sprintf(buffer, "user");
387 makeargs(buffer);
388 s = DOuser();
392 while(s >= 0) {
393 s = readline("ftp>", buffer, sizeof(buffer));
394 if(s < 0) break;
395 makeargs(buffer);
396 if(cmdargc == 0) continue;
397 for(cmd = commands; *cmd->name != '\0'; cmd++)
398 if(!strcmp(cmdargv[0], cmd->name))
399 break;
400 if(*cmd->name != '\0')
401 s = (*cmd->func)();
402 else {
403 s = 0;
404 printf("Command \"%s\" not recognized.\n", cmdargv[0]);
408 return(s);