00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <sys/types.h>
00010 #include <sys/stat.h>
00011 #include <stdio.h>
00012 #include <unistd.h>
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <fcntl.h>
00016 #include <errno.h>
00017
00018 #include "ftp.h"
00019 #include "file.h"
00020 #include "net.h"
00021
00022 _PROTOTYPE(static char *dir, (char *path, int full));
00023 _PROTOTYPE(static int asciisend, (int fd, int fdout));
00024 _PROTOTYPE(static int binarysend, (int fd, int fdout));
00025 _PROTOTYPE(static int asciirecv, (int fd, int fdin));
00026 _PROTOTYPE(static int binaryrecv, (int fd, int fdin));
00027 _PROTOTYPE(static int asciisize, (int fd, off_t *filesize));
00028 _PROTOTYPE(static off_t asciisetsize, (int fd, off_t filesize));
00029
00030 static char buffer[512 << sizeof(char *)];
00031 static char bufout[512 << sizeof(char *)];
00032 static char line2[512];
00033
00034 static char *dir(path, full)
00035 char *path;
00036 int full;
00037 {
00038 char cmd[128];
00039 static char name[32];
00040
00041 tmpnam(name);
00042
00043 if(full)
00044 sprintf(cmd, "ls -l %s > %s", path, name);
00045 else
00046 sprintf(cmd, "ls %s > %s", path, name);
00047
00048 system(cmd);
00049
00050 return(name);
00051 }
00052
00053 static int asciisend(fd, fdout)
00054 int fd;
00055 int fdout;
00056 {
00057 int s, len;
00058 char c;
00059 char *p;
00060 char *op, *ope;
00061 unsigned long total=0L;
00062
00063 if(atty) {
00064 printf("Sent ");
00065 fflush(stdout);
00066 }
00067
00068 op = bufout;
00069 ope = bufout + sizeof(bufout) - 3;
00070
00071 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
00072 total += (long)s;
00073 p = buffer;
00074 while(s-- > 0) {
00075 c = *p++;
00076 if(c == '\r') {
00077 *op++ = '\r';
00078 total++;
00079 }
00080 *op++ = c;
00081 if(op >= ope) {
00082 write(fdout, bufout, op - bufout);
00083 op = bufout;
00084 }
00085 }
00086 if(atty) {
00087 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
00088 fflush(stdout);
00089 }
00090 }
00091 if(op > bufout)
00092 write(fdout, bufout, op - bufout);
00093 if(atty) {
00094 printf("\n");
00095 fflush(stdout);
00096 }
00097
00098 return(s);
00099 }
00100
00101 static int binarysend(fd, fdout)
00102 int fd;
00103 int fdout;
00104 {
00105 int s;
00106 unsigned long total=0L;
00107
00108 if(atty) {
00109 printf("Sent ");
00110 fflush(stdout);
00111 }
00112
00113 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
00114 write(fdout, buffer, s);
00115 total += (long)s;
00116 if(atty) {
00117 printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
00118 fflush(stdout);
00119 }
00120 }
00121 if(atty) {
00122 printf("\n");
00123 fflush(stdout);
00124 }
00125
00126 return(s);
00127 }
00128
00129 int sendfile(fd, fdout)
00130 int fd;
00131 int fdout;
00132 {
00133 int s;
00134
00135 switch(type) {
00136 case TYPE_A:
00137 s = asciisend(fd, fdout);
00138 break;
00139 default:
00140 s = binarysend(fd, fdout);
00141 }
00142
00143 if(s < 0)
00144 return(-1);
00145 else
00146 return(0);
00147 }
00148
00149 static int asciirecv(fd, fdin)
00150 int fd;
00151 int fdin;
00152 {
00153 int s, len;
00154 int gotcr;
00155 char c;
00156 char *p;
00157 char *op, *ope;
00158 unsigned long total=0L;
00159
00160 if(isatty && fd > 2) {
00161 printf("Received ");
00162 fflush(stdout);
00163 }
00164 gotcr = 0;
00165 op = bufout; ope = bufout + sizeof(bufout) - 3;
00166 while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
00167 p = buffer;
00168 total += (long)s;
00169 while(s-- > 0) {
00170 c = *p++;
00171 if(gotcr) {
00172 gotcr = 0;
00173 if(c != '\n')
00174 *op++ = '\r';
00175 }
00176 if(c == '\r')
00177 gotcr = 1;
00178 else
00179 *op++ = c;
00180 if(op >= ope) {
00181 write(fd, bufout, op - bufout);
00182 op = bufout;
00183 }
00184 }
00185 if(atty && fd > 2) {
00186 printf("%11lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
00187 fflush(stdout);
00188 }
00189 }
00190 if(gotcr)
00191 *op++ = '\r';
00192 if(op > bufout)
00193 write(fd, bufout, op - bufout);
00194 if(atty && fd > 2) {
00195 printf("\n");
00196 fflush(stdout);
00197 }
00198 return(s);
00199 }
00200
00201 static binaryrecv(fd, fdin)
00202 int fd;
00203 int fdin;
00204 {
00205 int s;
00206 unsigned long total=0L;
00207
00208 if(atty && fd > 2) {
00209 printf("Received ");
00210 fflush(stdout);
00211 }
00212 while((s = read(fdin, buffer, sizeof(buffer))) > 0) {
00213 write(fd, buffer, s);
00214 total += (long)s;
00215 if(atty && fd > 2) {
00216 printf("%11lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total);
00217 fflush(stdout);
00218 }
00219 }
00220 if(atty && fd > 2) {
00221 printf("\n");
00222 fflush(stdout);
00223 }
00224 return(s);
00225 }
00226
00227 int recvfile(fd, fdin)
00228 int fd;
00229 int fdin;
00230 {
00231 int s;
00232
00233 switch(type) {
00234 case TYPE_A:
00235 s = asciirecv(fd, fdin);
00236 break;
00237 default:
00238 s = binaryrecv(fd, fdin);
00239 }
00240
00241 if(s < 0)
00242 return(-1);
00243 else
00244 return(0);
00245 }
00246
00247 int DOascii()
00248 {
00249 int s;
00250
00251 if(DOcmdcheck())
00252 return(0);
00253
00254 s = DOcommand("TYPE", "A");
00255
00256 type = TYPE_A;
00257
00258 return(s);
00259 }
00260
00261 int DObinary()
00262 {
00263 int s;
00264
00265 if(DOcmdcheck())
00266 return(0);
00267
00268 s = DOcommand("TYPE", "I");
00269
00270 type = TYPE_I;
00271
00272 return(s);
00273 }
00274
00275 int DOpwd()
00276 {
00277 int s;
00278
00279 if(DOcmdcheck())
00280 return(0);
00281
00282 s = DOcommand("PWD", "");
00283
00284 if(s == 500 || s == 502)
00285 s = DOcommand("XPWD", "");
00286
00287 return(s);
00288 }
00289
00290 int DOcd()
00291 {
00292 char *path;
00293 int s;
00294
00295 if(DOcmdcheck())
00296 return(0);
00297
00298 path = cmdargv[1];
00299
00300 if(cmdargc < 2) {
00301 readline("Path: ", line2, sizeof(line2));
00302 path = line2;
00303 }
00304
00305 if(!strcmp(path, ".."))
00306 s = DOcommand("CDUP", "");
00307 else
00308 s = DOcommand("CWD", path);
00309
00310 if(s == 500 || s == 502) {
00311 if(!strcmp(path, ".."))
00312 s = DOcommand("XCUP", "");
00313 else
00314 s = DOcommand("XCWD", path);
00315 }
00316
00317 return(s);
00318 }
00319
00320 int DOmkdir()
00321 {
00322 char *path;
00323 int s;
00324
00325 if(DOcmdcheck())
00326 return(0);
00327
00328 path = cmdargv[1];
00329
00330 if(cmdargc < 2) {
00331 readline("Directory: ", line2, sizeof(line2));
00332 path = line2;
00333 }
00334
00335 s = DOcommand("MKD", path);
00336
00337 if(s == 500 || s == 502)
00338 s = DOcommand("XMKD", path);
00339
00340 return(s);
00341 }
00342
00343 int DOrmdir()
00344 {
00345 char *path;
00346 int s;
00347
00348 if(DOcmdcheck())
00349 return(0);
00350
00351 path = cmdargv[1];
00352
00353 if(cmdargc < 2) {
00354 readline("Directory: ", line2, sizeof(line2));
00355 path = line2;
00356 }
00357
00358 s = DOcommand("RMD", path);
00359
00360 if(s == 500 || s == 502)
00361 s = DOcommand("XRMD", path);
00362
00363 return(s);
00364 }
00365
00366 int DOdelete()
00367 {
00368 char *file;
00369
00370 if(DOcmdcheck())
00371 return(0);
00372
00373 file = cmdargv[1];
00374
00375 if(cmdargc < 2) {
00376 readline("File: ", line2, sizeof(line2));
00377 file = line2;
00378 }
00379
00380 return(DOcommand("DELE", file));
00381 }
00382
00383 int DOmdtm()
00384 {
00385 char *file;
00386
00387 if(DOcmdcheck())
00388 return(0);
00389
00390 file = cmdargv[1];
00391
00392 if(cmdargc < 2) {
00393 readline("File: ", line2, sizeof(line2));
00394 file = line2;
00395 }
00396
00397 return(DOcommand("MDTM", file));
00398 }
00399
00400 int DOsize()
00401 {
00402 char *file;
00403
00404 if(DOcmdcheck())
00405 return(0);
00406
00407 file = cmdargv[1];
00408
00409 if(cmdargc < 2) {
00410 readline("File: ", line2, sizeof(line2));
00411 file = line2;
00412 }
00413
00414 return(DOcommand("SIZE", file));
00415 }
00416
00417 int DOstat()
00418 {
00419 char *file;
00420
00421 if(cmdargc < 2)
00422 if(!linkopen) {
00423 printf("You must \"OPEN\" a connection first.\n");
00424 return(0);
00425 } else
00426 return(DOcommand("STAT", ""));
00427
00428 if(DOcmdcheck())
00429 return(0);
00430
00431 file = cmdargv[1];
00432
00433 if(cmdargc < 2) {
00434 readline("File: ", line2, sizeof(line2));
00435 file = line2;
00436 }
00437
00438 return(DOcommand("STAT", file));
00439 }
00440
00441 int DOlist()
00442 {
00443 char *path;
00444 char *local;
00445 int fd;
00446 int s;
00447
00448 if(DOcmdcheck())
00449 return(0);
00450
00451 path = cmdargv[1];
00452
00453 if(cmdargc < 2)
00454 path = "";
00455
00456 if(cmdargc < 3)
00457 local = "";
00458 else
00459 local = cmdargv[2];
00460
00461 if(*local == '\0')
00462 fd = 1;
00463 else
00464 fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
00465
00466 if(fd < 0) {
00467 printf("Could not open local file %s. Error %s\n", local, strerror(errno));
00468 return(0);
00469 }
00470
00471 s = DOdata("LIST", path, RETR, fd);
00472
00473 if(fd > 2)
00474 close(fd);
00475
00476 return(s);
00477 }
00478
00479 int DOnlst()
00480 {
00481 char *path;
00482 char *local;
00483 int fd;
00484 int s;
00485
00486 if(DOcmdcheck())
00487 return(0);
00488
00489 path = cmdargv[1];
00490
00491 if(cmdargc < 2)
00492 path = "";
00493
00494 if(cmdargc < 3)
00495 local = "";
00496 else
00497 local = cmdargv[2];
00498
00499 if(*local == '\0')
00500 fd = 1;
00501 else
00502 fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666);
00503
00504 if(fd < 0) {
00505 printf("Could not open local file %s. Error %s\n", local, strerror(errno));
00506 return(0);
00507 }
00508
00509 s = DOdata("NLST", path, RETR, fd);
00510
00511 if(fd > 2)
00512 close(fd);
00513
00514 return(s);
00515 }
00516
00517 int DOretr()
00518 {
00519 char *file, *localfile;
00520 int fd;
00521 int s;
00522
00523 if(DOcmdcheck())
00524 return(0);
00525
00526 file = cmdargv[1];
00527
00528 if(cmdargc < 2) {
00529 readline("Remote File: ", line2, sizeof(line2));
00530 file = line2;
00531 }
00532
00533 if(cmdargc < 3)
00534 localfile = file;
00535 else
00536 localfile = cmdargv[2];
00537
00538 fd = open(localfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
00539
00540 if(fd < 0) {
00541 printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
00542 return(0);
00543 }
00544
00545 s = DOdata("RETR", file, RETR, fd);
00546
00547 close(fd);
00548
00549 return(s);
00550 }
00551
00552 int DOrretr()
00553 {
00554 char *file, *localfile;
00555 int fd;
00556 int s;
00557 off_t filesize;
00558 char restart[16];
00559
00560 if(DOcmdcheck())
00561 return(0);
00562
00563 file = cmdargv[1];
00564
00565 if(cmdargc < 2) {
00566 readline("Remote File: ", line2, sizeof(line2));
00567 file = line2;
00568 }
00569
00570 if(cmdargc < 3)
00571 localfile = file;
00572 else
00573 localfile = cmdargv[2];
00574
00575 fd = open(localfile, O_RDWR);
00576
00577 if(fd < 0) {
00578 printf("Could not open local file %s. Error %s\n", localfile, strerror(errno));
00579 return(0);
00580 }
00581
00582 if(type == TYPE_A) {
00583 if(asciisize(fd, &filesize)) {
00584 printf("Could not determine ascii file size of %s\n", localfile);
00585 close(fd);
00586 return(0);
00587 }
00588 } else
00589 filesize = lseek(fd, 0, SEEK_END);
00590
00591 sprintf(restart, "%lu", filesize);
00592
00593 s = DOcommand("REST", restart);
00594
00595 if(s != 350) {
00596 close(fd);
00597 return(s);
00598 }
00599
00600 s = DOdata("RETR", file, RETR, fd);
00601
00602 close(fd);
00603
00604 return(s);
00605 }
00606
00607 int DOMretr()
00608 {
00609 char *files;
00610 int fd, s;
00611 FILE *fp;
00612 char name[32];
00613
00614 if(DOcmdcheck())
00615 return(0);
00616
00617 files = cmdargv[1];
00618
00619 if(cmdargc < 2) {
00620 readline("Files: ", line2, sizeof(line2));
00621 files = line2;
00622 }
00623
00624 tmpnam(name);
00625
00626 fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
00627
00628 if(fd < 0) {
00629 printf("Could not open local file %s. Error %s\n", name, strerror(errno));
00630 return(0);
00631 }
00632
00633 s = DOdata("NLST", files, RETR, fd);
00634
00635 close(fd);
00636
00637 if(s == 226) {
00638 fp = fopen(name, "r");
00639 unlink(name);
00640 if(fp == (FILE *)NULL) {
00641 printf("Unable to open file listing.\n");
00642 return(0);
00643 }
00644 while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
00645 line2[strlen(line2)-1] = '\0';
00646 printf("Retrieving file: %s\n", line2); fflush(stdout);
00647 fd = open(line2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
00648 if(fd < 0)
00649 printf("Unable to open local file %s\n", line2);
00650 else {
00651 s = DOdata("RETR", line2, RETR, fd);
00652 close(fd);
00653 if(s < 0) break;
00654 }
00655 }
00656 fclose(fp);
00657 } else
00658 unlink(name);
00659
00660 return(s);
00661 }
00662
00663 int DOappe()
00664 {
00665 char *file, *remotefile;
00666 int fd;
00667 int s;
00668
00669 if(DOcmdcheck())
00670 return(0);
00671
00672 file = cmdargv[1];
00673
00674 if(cmdargc < 2) {
00675 readline("Local File: ", line2, sizeof(line2));
00676 file = line2;
00677 }
00678
00679 if(cmdargc < 3)
00680 remotefile = file;
00681 else
00682 remotefile = cmdargv[2];
00683
00684 fd = open(file, O_RDONLY);
00685
00686 if(fd < 0) {
00687 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
00688 return(0);
00689 }
00690
00691 s = DOdata("APPE", remotefile, STOR, fd);
00692
00693 close(fd);
00694
00695 return(s);
00696 }
00697
00698 int DOstor()
00699 {
00700 char *file, *remotefile;
00701 int fd;
00702 int s;
00703
00704 if(DOcmdcheck())
00705 return(0);
00706
00707 file = cmdargv[1];
00708
00709 if(cmdargc < 2) {
00710 readline("Local File: ", line2, sizeof(line2));
00711 file = line2;
00712 }
00713
00714 if(cmdargc < 3)
00715 remotefile = file;
00716 else
00717 remotefile = cmdargv[2];
00718
00719 fd = open(file, O_RDONLY);
00720
00721 if(fd < 0) {
00722 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
00723 return(0);
00724 }
00725
00726 s = DOdata("STOR", remotefile, STOR, fd);
00727
00728 close(fd);
00729
00730 return(s);
00731 }
00732
00733 int DOrstor()
00734 {
00735 char *file, *remotefile;
00736 int fd;
00737 int s;
00738 off_t filesize, rmtsize;
00739 char restart[16];
00740
00741 if(DOcmdcheck())
00742 return(0);
00743
00744 file = cmdargv[1];
00745
00746 if(cmdargc < 2) {
00747 readline("Local File: ", line2, sizeof(line2));
00748 file = line2;
00749 }
00750
00751 if(cmdargc < 3)
00752 remotefile = file;
00753 else
00754 remotefile = cmdargv[2];
00755
00756 s = DOcommand("SIZE", remotefile);
00757
00758 if(s != 215)
00759 return(s);
00760
00761 rmtsize = atol(reply+4);
00762
00763 fd = open(file, O_RDONLY);
00764
00765 if(fd < 0) {
00766 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
00767 return(0);
00768 }
00769
00770 if(type == TYPE_A)
00771 filesize = asciisetsize(fd, rmtsize);
00772 else
00773 filesize = lseek(fd, rmtsize, SEEK_SET);
00774
00775 if(filesize != rmtsize) {
00776 printf("Could not set file start of %s\n", file);
00777 close(fd);
00778 return(0);
00779 }
00780
00781 sprintf(restart, "%lu", rmtsize);
00782
00783 s = DOcommand("REST", restart);
00784
00785 if(s != 350) {
00786 close(fd);
00787 return(s);
00788 }
00789
00790 s = DOdata("STOR", remotefile, STOR, fd);
00791
00792 close(fd);
00793
00794 return(s);
00795 }
00796
00797 int DOstou()
00798 {
00799 char *file, *remotefile;
00800 int fd;
00801 int s;
00802
00803 if(DOcmdcheck())
00804 return(0);
00805
00806 file = cmdargv[1];
00807
00808 if(cmdargc < 2) {
00809 readline("Local File: ", line2, sizeof(line2));
00810 file = line2;
00811 }
00812
00813 if(cmdargc < 3)
00814 remotefile = file;
00815 else
00816 remotefile = cmdargv[2];
00817
00818 fd = open(file, O_RDONLY);
00819
00820 if(fd < 0) {
00821 printf("Could not open local file %s. Error %s\n", file, strerror(errno));
00822 return(0);
00823 }
00824
00825 s = DOdata("STOU", remotefile, STOR, fd);
00826
00827 close(fd);
00828
00829 return(s);
00830 }
00831
00832 int DOMstor()
00833 {
00834 char *files;
00835 char *name;
00836 int fd, s;
00837 FILE *fp;
00838
00839 if(DOcmdcheck())
00840 return(0);
00841
00842 files = cmdargv[1];
00843
00844 if(cmdargc < 2) {
00845 readline("Files: ", line2, sizeof(line2));
00846 files = line2;
00847 }
00848
00849 name = dir(files, 0);
00850
00851 fp = fopen(name, "r");
00852
00853 if(fp == (FILE *)NULL) {
00854 printf("Unable to open listing file.\n");
00855 return(0);
00856 }
00857
00858 while(fgets(line2, sizeof(line2), fp) != (char *)NULL) {
00859 line2[strlen(line2)-1] = '\0';
00860 printf("Sending file: %s\n", line2); fflush(stdout);
00861 fd = open(line2, O_RDONLY);
00862 if(fd < 0)
00863 printf("Unable to open local file %s\n", line2);
00864 else {
00865 s = DOdata("STOR", line2, STOR, fd);
00866 close(fd);
00867 if(s < 0) break;
00868 }
00869 }
00870 fclose(fp);
00871 unlink(name);
00872
00873 return(s);
00874 }
00875
00876 static int asciisize(fd, filesize)
00877 int fd;
00878 off_t *filesize;
00879 {
00880 unsigned long count;
00881 char *p, *pp;
00882 int cnt;
00883
00884 count = 0;
00885
00886 while((cnt = read(fd, buffer, sizeof(buffer))) > 0) {
00887 p = buffer; pp = buffer + cnt;
00888 count += cnt;
00889 while(p < pp)
00890 if(*p++ == '\n')
00891 count++;
00892 }
00893
00894 if(cnt == 0) {
00895 *filesize = count;
00896 return(0);
00897 }
00898
00899 return(1);
00900 }
00901
00902 static off_t asciisetsize(fd, filesize)
00903 int fd;
00904 off_t filesize;
00905 {
00906 off_t sp;
00907 int s;
00908
00909 sp = 0;
00910
00911 while(sp < filesize) {
00912 s = read(fd, buffer, 1);
00913 if(s < 0)
00914 return(-1);
00915 if(s == 0) break;
00916 sp++;
00917 if(*buffer == '\n')
00918 sp++;
00919 }
00920
00921 return(sp);
00922 }