source: trunk/minix/commands/ftp/file.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 13.2 KB
Line 
1/* file.c
2 *
3 * This file is part of ftp.
4 *
5 *
6 * 01/25/96 Initial Release Michael Temari, <temari@ix.netcom.com>
7 */
8
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <stdio.h>
12#include <unistd.h>
13#include <string.h>
14#include <stdlib.h>
15#include <fcntl.h>
16#include <errno.h>
17
18#include "ftp.h"
19#include "file.h"
20#include "net.h"
21
22_PROTOTYPE(static char *dir, (char *path, int full));
23_PROTOTYPE(static int asciisend, (int fd, int fdout));
24_PROTOTYPE(static int binarysend, (int fd, int fdout));
25_PROTOTYPE(static int asciirecv, (int fd, int fdin));
26_PROTOTYPE(static int binaryrecv, (int fd, int fdin));
27_PROTOTYPE(static int asciisize, (int fd, off_t *filesize));
28_PROTOTYPE(static off_t asciisetsize, (int fd, off_t filesize));
29
30static char buffer[512 << sizeof(char *)];
31static char bufout[512 << sizeof(char *)];
32static char line2[512];
33
34static char *dir(path, full)
35char *path;
36int full;
37{
38char cmd[128];
39static char name[32];
40
41 tmpnam(name);
42
43 if(full)
44 sprintf(cmd, "ls -l %s > %s", path, name);
45 else
46 sprintf(cmd, "ls %s > %s", path, name);
47
48 system(cmd);
49
50 return(name);
51}
52
53static int asciisend(fd, fdout)
54int fd;
55int fdout;
56{
57int s, len;
58char c;
59char *p;
60char *op, *ope;
61unsigned long total=0L;
62
63 if(atty) {
64 printf("Sent ");
65 fflush(stdout);
66 }
67
68 op = bufout;
69 ope = bufout + sizeof(bufout) - 3;
70
71 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
72 total += (long)s;
73 p = buffer;
74 while(s-- > 0) {
75 c = *p++;
76 if(c == '\r') {
77 *op++ = '\r';
78 total++;
79 }
80 *op++ = c;
81 if(op >= ope) {
82 write(fdout, bufout, op - bufout);
83 op = bufout;
84 }
85 }
86 if(atty) {
87 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
88 fflush(stdout);
89 }
90 }
91 if(op > bufout)
92 write(fdout, bufout, op - bufout);
93 if(atty) {
94 printf("\n");
95 fflush(stdout);
96 }
97
98 return(s);
99}
100
101static int binarysend(fd, fdout)
102int fd;
103int fdout;
104{
105int s;
106unsigned long total=0L;
107
108 if(atty) {
109 printf("Sent ");
110 fflush(stdout);
111 }
112
113 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
114 write(fdout, buffer, s);
115 total += (long)s;
116 if(atty) {
117 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
118 fflush(stdout);
119 }
120 }
121 if(atty) {
122 printf("\n");
123 fflush(stdout);
124 }
125
126 return(s);
127}
128
129int sendfile(fd, fdout)
130int fd;
131int fdout;
132{
133int s;
134
135 switch(type) {
136 case TYPE_A:
137 s = asciisend(fd, fdout);
138 break;
139 default:
140 s = binarysend(fd, fdout);
141 }
142
143 if(s < 0)
144 return(-1);
145 else
146 return(0);
147}
148
149static int asciirecv(fd, fdin)
150int fd;
151int fdin;
152{
153int s, len;
154int gotcr;
155char c;
156char *p;
157char *op, *ope;
158unsigned long total=0L;
159
160 if(isatty && fd > 2) {
161 printf("Received ");
162 fflush(stdout);
163 }
164 gotcr = 0;
165 op = bufout; ope = bufout + sizeof(bufout) - 3;
166 while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
167 p = buffer;
168 total += (long)s;
169 while(s-- > 0) {
170 c = *p++;
171 if(gotcr) {
172 gotcr = 0;
173 if(c != '\n')
174 *op++ = '\r';
175 }
176 if(c == '\r')
177 gotcr = 1;
178 else
179 *op++ = c;
180 if(op >= ope) {
181 write(fd, bufout, op - bufout);
182 op = bufout;
183 }
184 }
185 if(atty && fd > 2) {
186 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
187 fflush(stdout);
188 }
189 }
190 if(gotcr)
191 *op++ = '\r';
192 if(op > bufout)
193 write(fd, bufout, op - bufout);
194 if(atty && fd > 2) {
195 printf("\n");
196 fflush(stdout);
197 }
198 return(s);
199}
200
201static binaryrecv(fd, fdin)
202int fd;
203int fdin;
204{
205int s;
206unsigned long total=0L;
207
208 if(atty && fd > 2) {
209 printf("Received ");
210 fflush(stdout);
211 }
212 while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
213 write(fd, buffer, s);
214 total += (long)s;
215 if(atty && fd > 2) {
216 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
217 fflush(stdout);
218 }
219 }
220 if(atty && fd > 2) {
221 printf("\n");
222 fflush(stdout);
223 }
224 return(s);
225}
226
227int recvfile(fd, fdin)
228int fd;
229int fdin;
230{
231int s;
232
233 switch(type) {
234 case TYPE_A:
235 s = asciirecv(fd, fdin);
236 break;
237 default:
238 s = binaryrecv(fd, fdin);
239 }
240
241 if(s < 0)
242 return(-1);
243 else
244 return(0);
245}
246
247int DOascii()
248{
249int s;
250
251 if(DOcmdcheck())
252 return(0);
253
254 s = DOcommand("TYPE", "A");
255
256 type = TYPE_A;
257
258 return(s);
259}
260
261int DObinary()
262{
263int s;
264
265 if(DOcmdcheck())
266 return(0);
267
268 s = DOcommand("TYPE", "I");
269
270 type = TYPE_I;
271
272 return(s);
273}
274
275int DOpwd()
276{
277int s;
278
279 if(DOcmdcheck())
280 return(0);
281
282 s = DOcommand("PWD", "");
283
284 if(s == 500 || s == 502)
285 s = DOcommand("XPWD", "");
286
287 return(s);
288}
289
290int DOcd()
291{
292char *path;
293int s;
294
295 if(DOcmdcheck())
296 return(0);
297
298 path = cmdargv[1];
299
300 if(cmdargc < 2) {
301 readline("Path: ", line2, sizeof(line2));
302 path = line2;
303 }
304
305 if(!strcmp(path, ".."))
306 s = DOcommand("CDUP", "");
307 else
308 s = DOcommand("CWD", path);
309
310 if(s == 500 || s == 502) {
311 if(!strcmp(path, ".."))
312 s = DOcommand("XCUP", "");
313 else
314 s = DOcommand("XCWD", path);
315 }
316
317 return(s);
318}
319
320int DOmkdir()
321{
322char *path;
323int s;
324
325 if(DOcmdcheck())
326 return(0);
327
328 path = cmdargv[1];
329
330 if(cmdargc < 2) {
331 readline("Directory: ", line2, sizeof(line2));
332 path = line2;
333 }
334
335 s = DOcommand("MKD", path);
336
337 if(s == 500 || s == 502)
338 s = DOcommand("XMKD", path);
339
340 return(s);
341}
342
343int DOrmdir()
344{
345char *path;
346int s;
347
348 if(DOcmdcheck())
349 return(0);
350
351 path = cmdargv[1];
352
353 if(cmdargc < 2) {
354 readline("Directory: ", line2, sizeof(line2));
355 path = line2;
356 }
357
358 s = DOcommand("RMD", path);
359
360 if(s == 500 || s == 502)
361 s = DOcommand("XRMD", path);
362
363 return(s);
364}
365
366int DOdelete()
367{
368char *file;
369
370 if(DOcmdcheck())
371 return(0);
372
373 file = cmdargv[1];
374
375 if(cmdargc < 2) {
376 readline("File: ", line2, sizeof(line2));
377 file = line2;
378 }
379
380 return(DOcommand("DELE", file));
381}
382
383int DOmdtm()
384{
385char *file;
386
387 if(DOcmdcheck())
388 return(0);
389
390 file = cmdargv[1];
391
392 if(cmdargc < 2) {
393 readline("File: ", line2, sizeof(line2));
394 file = line2;
395 }
396
397 return(DOcommand("MDTM", file));
398}
399
400int DOsize()
401{
402char *file;
403
404 if(DOcmdcheck())
405 return(0);
406
407 file = cmdargv[1];
408
409 if(cmdargc < 2) {
410 readline("File: ", line2, sizeof(line2));
411 file = line2;
412 }
413
414 return(DOcommand("SIZE", file));
415}
416
417int DOstat()
418{
419char *file;
420
421 if(cmdargc < 2)
422 if(!linkopen) {
423 printf("You must \"OPEN\" a connection first.\n");
424 return(0);
425 } else
426 return(DOcommand("STAT", ""));
427
428 if(DOcmdcheck())
429 return(0);
430
431 file = cmdargv[1];
432
433 if(cmdargc < 2) {
434 readline("File: ", line2, sizeof(line2));
435 file = line2;
436 }
437
438 return(DOcommand("STAT", file));
439}
440
441int DOlist()
442{
443char *path;
444char *local;
445int fd;
446int s;
447
448 if(DOcmdcheck())
449 return(0);
450
451 path = cmdargv[1];
452
453 if(cmdargc < 2)
454 path = "";
455
456 if(cmdargc < 3)
457 local = "";
458 else
459 local = cmdargv[2];
460
461 if(*local == '\0')
462 fd = 1;
463 else
464 fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
465
466 if(fd < 0) {
467 printf("Could not open local file %s. Error %s\n", local, strerror(errno));
468 return(0);
469 }
470
471 s = DOdata("LIST", path, RETR, fd);
472
473 if(fd > 2)
474 close(fd);
475
476 return(s);
477}
478
479int DOnlst()
480{
481char *path;
482char *local;
483int fd;
484int s;
485
486 if(DOcmdcheck())
487 return(0);
488
489 path = cmdargv[1];
490
491 if(cmdargc < 2)
492 path = "";
493
494 if(cmdargc < 3)
495 local = "";
496 else
497 local = cmdargv[2];
498
499 if(*local == '\0')
500 fd = 1;
501 else
502 fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
503
504 if(fd < 0) {
505 printf("Could not open local file %s. Error %s\n", local, strerror(errno));
506 return(0);
507 }
508
509 s = DOdata("NLST", path, RETR, fd);
510
511 if(fd > 2)
512 close(fd);
513
514 return(s);
515}
516
517int DOretr()
518{
519char *file, *localfile;
520int fd;
521int s;
522
523 if(DOcmdcheck())
524 return(0);
525
526 file = cmdargv[1];
527
528 if(cmdargc < 2) {
529 readline("Remote File: ", line2, sizeof(line2));
530 file = line2;
531 }
532
533 if(cmdargc < 3)
534 localfile = file;
535 else
536 localfile = cmdargv[2];
537
538 fd = open(localfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
539
540 if(fd < 0) {
541 printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
542 return(0);
543 }
544
545 s = DOdata("RETR", file, RETR, fd);
546
547 close(fd);
548
549 return(s);
550}
551
552int DOrretr()
553{
554char *file, *localfile;
555int fd;
556int s;
557off_t filesize;
558char restart[16];
559
560 if(DOcmdcheck())
561 return(0);
562
563 file = cmdargv[1];
564
565 if(cmdargc < 2) {
566 readline("Remote File: ", line2, sizeof(line2));
567 file = line2;
568 }
569
570 if(cmdargc < 3)
571 localfile = file;
572 else
573 localfile = cmdargv[2];
574
575 fd = open(localfile, O_RDWR);
576
577 if(fd < 0) {
578 printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
579 return(0);
580 }
581
582 if(type == TYPE_A) {
583 if(asciisize(fd, &filesize)) {
584 printf("Could not determine ascii file size of %s\n", localfile);
585 close(fd);
586 return(0);
587 }
588 } else
589 filesize = lseek(fd, 0, SEEK_END);
590
591 sprintf(restart, "%lu", filesize);
592
593 s = DOcommand("REST", restart);
594
595 if(s != 350) {
596 close(fd);
597 return(s);
598 }
599
600 s = DOdata("RETR", file, RETR, fd);
601
602 close(fd);
603
604 return(s);
605}
606
607int DOMretr()
608{
609char *files;
610int fd, s;
611FILE *fp;
612char name[32];
613
614 if(DOcmdcheck())
615 return(0);
616
617 files = cmdargv[1];
618
619 if(cmdargc < 2) {
620 readline("Files: ", line2, sizeof(line2));
621 files = line2;
622 }
623
624 tmpnam(name);
625
626 fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
627
628 if(fd < 0) {
629 printf("Could not open local file %s. Error %s\n", name, strerror(errno));
630 return(0);
631 }
632
633 s = DOdata("NLST", files, RETR, fd);
634
635 close(fd);
636
637 if(s == 226) {
638 fp = fopen(name, "r");
639 unlink(name);
640 if(fp == (FILE *)NULL) {
641 printf("Unable to open file listing.\n");
642 return(0);
643 }
644 while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
645 line2[strlen(line2)-1] = '\0';
646 printf("Retrieving file: %s\n", line2); fflush(stdout);
647 fd = open(line2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
648 if(fd < 0)
649 printf("Unable to open local file %s\n", line2);
650 else {
651 s = DOdata("RETR", line2, RETR, fd);
652 close(fd);
653 if(s < 0) break;
654 }
655 }
656 fclose(fp);
657 } else
658 unlink(name);
659
660 return(s);
661}
662
663int DOappe()
664{
665char *file, *remotefile;
666int fd;
667int s;
668
669 if(DOcmdcheck())
670 return(0);
671
672 file = cmdargv[1];
673
674 if(cmdargc < 2) {
675 readline("Local File: ", line2, sizeof(line2));
676 file = line2;
677 }
678
679 if(cmdargc < 3)
680 remotefile = file;
681 else
682 remotefile = cmdargv[2];
683
684 fd = open(file, O_RDONLY);
685
686 if(fd < 0) {
687 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
688 return(0);
689 }
690
691 s = DOdata("APPE", remotefile, STOR, fd);
692
693 close(fd);
694
695 return(s);
696}
697
698int DOstor()
699{
700char *file, *remotefile;
701int fd;
702int s;
703
704 if(DOcmdcheck())
705 return(0);
706
707 file = cmdargv[1];
708
709 if(cmdargc < 2) {
710 readline("Local File: ", line2, sizeof(line2));
711 file = line2;
712 }
713
714 if(cmdargc < 3)
715 remotefile = file;
716 else
717 remotefile = cmdargv[2];
718
719 fd = open(file, O_RDONLY);
720
721 if(fd < 0) {
722 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
723 return(0);
724 }
725
726 s = DOdata("STOR", remotefile, STOR, fd);
727
728 close(fd);
729
730 return(s);
731}
732
733int DOrstor()
734{
735char *file, *remotefile;
736int fd;
737int s;
738off_t filesize, rmtsize;
739char restart[16];
740
741 if(DOcmdcheck())
742 return(0);
743
744 file = cmdargv[1];
745
746 if(cmdargc < 2) {
747 readline("Local File: ", line2, sizeof(line2));
748 file = line2;
749 }
750
751 if(cmdargc < 3)
752 remotefile = file;
753 else
754 remotefile = cmdargv[2];
755
756 s = DOcommand("SIZE", remotefile);
757
758 if(s != 215)
759 return(s);
760
761 rmtsize = atol(reply+4);
762
763 fd = open(file, O_RDONLY);
764
765 if(fd < 0) {
766 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
767 return(0);
768 }
769
770 if(type == TYPE_A)
771 filesize = asciisetsize(fd, rmtsize);
772 else
773 filesize = lseek(fd, rmtsize, SEEK_SET);
774
775 if(filesize != rmtsize) {
776 printf("Could not set file start of %s\n", file);
777 close(fd);
778 return(0);
779 }
780
781 sprintf(restart, "%lu", rmtsize);
782
783 s = DOcommand("REST", restart);
784
785 if(s != 350) {
786 close(fd);
787 return(s);
788 }
789
790 s = DOdata("STOR", remotefile, STOR, fd);
791
792 close(fd);
793
794 return(s);
795}
796
797int DOstou()
798{
799char *file, *remotefile;
800int fd;
801int s;
802
803 if(DOcmdcheck())
804 return(0);
805
806 file = cmdargv[1];
807
808 if(cmdargc < 2) {
809 readline("Local File: ", line2, sizeof(line2));
810 file = line2;
811 }
812
813 if(cmdargc < 3)
814 remotefile = file;
815 else
816 remotefile = cmdargv[2];
817
818 fd = open(file, O_RDONLY);
819
820 if(fd < 0) {
821 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
822 return(0);
823 }
824
825 s = DOdata("STOU", remotefile, STOR, fd);
826
827 close(fd);
828
829 return(s);
830}
831
832int DOMstor()
833{
834char *files;
835char *name;
836int fd, s;
837FILE *fp;
838
839 if(DOcmdcheck())
840 return(0);
841
842 files = cmdargv[1];
843
844 if(cmdargc < 2) {
845 readline("Files: ", line2, sizeof(line2));
846 files = line2;
847 }
848
849 name = dir(files, 0);
850
851 fp = fopen(name, "r");
852
853 if(fp == (FILE *)NULL) {
854 printf("Unable to open listing file.\n");
855 return(0);
856 }
857
858 while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
859 line2[strlen(line2)-1] = '\0';
860 printf("Sending file: %s\n", line2); fflush(stdout);
861 fd = open(line2, O_RDONLY);
862 if(fd < 0)
863 printf("Unable to open local file %s\n", line2);
864 else {
865 s = DOdata("STOR", line2, STOR, fd);
866 close(fd);
867 if(s < 0) break;
868 }
869 }
870 fclose(fp);
871 unlink(name);
872
873 return(s);
874}
875
876static int asciisize(fd, filesize)
877int fd;
878off_t *filesize;
879{
880unsigned long count;
881char *p, *pp;
882int cnt;
883
884 count = 0;
885
886 while((cnt = read(fd, buffer, sizeof(buffer))) > 0) {
887 p = buffer; pp = buffer + cnt;
888 count += cnt;
889 while(p < pp)
890 if(*p++ == '\n')
891 count++;
892 }
893
894 if(cnt == 0) {
895 *filesize = count;
896 return(0);
897 }
898
899 return(1);
900}
901
902static off_t asciisetsize(fd, filesize)
903int fd;
904off_t filesize;
905{
906off_t sp;
907int s;
908
909 sp = 0;
910
911 while(sp < filesize) {
912 s = read(fd, buffer, 1);
913 if(s < 0)
914 return(-1);
915 if(s == 0) break;
916 sp++;
917 if(*buffer == '\n')
918 sp++;
919 }
920
921 return(sp);
922}
Note: See TracBrowser for help on using the repository browser.