home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / tcpiptk / rcopy / rcopy.c next >
Text File  |  1999-05-11  |  21KB  |  568 lines

  1. /********************************************************copyrite.xic********/
  2. /*                                                                          */
  3. /*   Licensed Materials - Property of IBM                                   */
  4. /*   IBM TCP/IP for OS/2                                                    */
  5. /*   (C) Copyright IBM Corporation. 1996.                                   */
  6. /*                                                                          */
  7. /*   All rights reserved.                                                   */
  8. /*                                                                          */
  9. /*   US Government Users Restricted Rights -                                */
  10. /*   Use, duplication or disclosure restricted by GSA ADP Schedule          */
  11. /*   Contract with IBM Corp.                                                */
  12. /*                                                                          */
  13. /*--------------------------------------------------------------------------*/
  14. /*                                                                          */
  15. /*  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is             */
  16. /*  sample code created by IBM Corporation. This sample code is not         */
  17. /*  part of any standard or IBM product and is provided to you solely       */
  18. /*  for  the purpose of assisting you in the development of your            */
  19. /*  applications.  The code is provided "AS IS", without                    */
  20. /*  warranty of any kind.  IBM shall not be liable for any damages          */
  21. /*  arising out of your use of the sample code, even if they have been      */
  22. /*  advised of the possibility of such damages.                             */
  23. /*                                                                          */
  24. /*--------------------------------------------------------------------------*/
  25. /*   LIMITATIONS:                                                           */
  26. /*     -Assumes TOTAL directory copy.  ie: no pattern checking              */
  27. /*     -May not work to Servers requiring ACCOUNT info                      */
  28. /*     -The "get" function works with FTPD in TCP/IP for OS/2 Warp V4.0 and */
  29. /*      some Unix FTDs.  Basically the "get" function anticipates return    */
  30. /*      data from FTPD as below:                                            */
  31. /*                                                                          */
  32. /*         file1                                                            */
  33. /*         file2                                                            */
  34. /*         ...                                                              */
  35. /*         subdir1:            <-- subdirectory name ends with a ':'        */
  36. /*         subdir1_file1       <-- file(s) in the subdirectory              */
  37. /*         subdir1_file2                                                    */
  38. /*         ....                                                             */
  39. /*                             <-- a blank line                             */
  40. /*         subdir2:                                                         */
  41. /*         subdir2_file1                                                    */
  42. /*         ....                                                             */
  43. /* Modification History:                                                    */
  44. /* Date:      By:   Tag:    Desc:                                           */
  45. /* 09.16.96   DRC   DRC01   Added check for Borland compiler                */
  46. /* 09.26.96   DRC   DRC02   Added check for Watcom Compiler and!!           */
  47. /*                          put jump around _chdrive - it does not exist    */
  48. /*                          in the Watcom compiler. The options are:        */
  49. /*                          let _chdir change drives also or -              */
  50. /*                          use _dos_setdrive.                              */
  51. /* 09.30.96   DRC   DRC03   Changed UCHAR definition to CHAR for tmp -      */
  52. /*                          error <NOT ANSI COMPATABLE> from Metaware       */
  53. /*                          compiler.                                       */
  54. /* 09.30.96   DRC           removed unreferenced variables                  */
  55. /********************************************************copyrite.xic********/
  56. #define  INCL_DOSFILEMGR
  57. #include <os2.h>
  58. #include <direct.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <ctype.h>
  63. #include <ftpapi.h>
  64.  
  65. #include <fcntl.h>
  66. #include <sys/types.h>
  67. #include <sys/stat.h>
  68.  
  69. #define MAX_FILEHANDLES  100L
  70. #define MAX_FILENAME_LEN 512
  71.  
  72. /*   DRC01 && DRC02
  73. ** Define some variables to exclude a prefix "_"
  74. */
  75.  
  76. #if defined(__BORLANDC__) || (__WATCOMC__)
  77.  
  78. #define      _chdir      chdir
  79. #define      _mkdir      mkdir
  80. #define      _getcwd      getcwd
  81. #define      _unlink      unlink
  82.  
  83. #endif
  84.  
  85.  
  86. /** Function Prototypes **/
  87. int  sendfiles(char *);
  88. void getfiles(void);
  89. int  mygets(char in[], int, FILE *);
  90. void usage(void);
  91. void ftperror(int);
  92.  
  93. char local[MAX_FILENAME_LEN+1];
  94. int  transfertype = T_BINARY;
  95. char *host, *user, *passwd;
  96. char *accnt = NULL;
  97. char locpath[MAX_FILENAME_LEN+1] = "";
  98. char destpath[MAX_FILENAME_LEN+1];
  99. char out[MAX_FILENAME_LEN+1];
  100. char host_sys_buf[MAX_FILENAME_LEN+1];            /* Store Host System Type */
  101. BOOL debug = FALSE;
  102.  
  103.  
  104. /****************************************************************************/
  105. /** Function: main()                                                       **/
  106. /** Purpose : Parse input args & call proper PUT/GET function              **/
  107. /****************************************************************************/
  108. int main(int argc, char *argv[], char *envp[]) {
  109.    APIRET apirc;
  110.    int i, rc, validarg = 0;
  111.    ULONG curmaxfh;
  112.    char ftptrc[] = "FTPAPI.TRC";
  113.    BOOL willput = TRUE;
  114.    char *curpath;
  115.    LONG reqcount = 0;
  116.  
  117.    /***  Check input arguments  ***/
  118.    for (i =1; i <argc; i++) {
  119.       if (argv[i][0] == '-') {
  120.        switch (argv[i][1]) {
  121.           case 'a':
  122.             case 'A': /* Account info  */
  123.                      accnt = &argv[i][2];
  124.                      break;
  125.  
  126.             case 'l':
  127.             case 'L': /* Local Host path */
  128.                      strncpy(locpath, &argv[i][2], MAX_FILENAME_LEN);
  129.                      locpath[0] = toupper((int)locpath[0]);
  130.                      break;
  131.  
  132.             case 'h':
  133.             case 'H': /* Remote Host */
  134.                      host = &argv[i][2];
  135.                      validarg++;
  136.                      break;
  137.  
  138.             case 'u':
  139.             case 'U': /* Userid on Remote */
  140.                      user = &argv[i][2];
  141.                      validarg++;
  142.                      break;
  143.  
  144.             case 'p':
  145.             case 'P': /* Password on Remote Host (may not be required) */
  146.                      passwd = &argv[i][2];
  147.                      break;
  148.  
  149.             case 'r':
  150.             case 'R': /* Remote directory */
  151.                      strncpy(destpath, &argv[i][2], MAX_FILENAME_LEN);
  152.                      destpath[0] = toupper((int)destpath[0]);
  153.                  break;
  154.  
  155.             case 'd':
  156.             case 'D': /* Debug & trace info */
  157.                      fprintf(stdout, " Debug ON.  Output to RCOPY.TRC\n");
  158.                      debug = TRUE;
  159.                      ftptrcon("RCOPY.TRC", M_OVERLAY);
  160.                      setbuf(stdout, 0);
  161.                      setbuf(stderr, 0);
  162.                      break;
  163.  
  164.             case '?':
  165.             default :
  166.                      usage();
  167.                      break;
  168.          } /*end sw*/
  169.       } else /*endif*/
  170.          if (strcmpi(argv[i], "put") == 0)
  171.             willput = TRUE;
  172.          else
  173.           if (strcmpi(argv[i], "get") == 0)
  174.              willput = FALSE;
  175.           else
  176.            if (strcmpi(argv[i], "ascii") == 0)
  177.               transfertype = T_ASCII;
  178.            else
  179.             if (strcmpi(argv[i], "binary") == 0)
  180.                transfertype = T_BINARY;
  181.    } /*endfor*/
  182.  
  183.  
  184.    if (validarg < 2) {  /* Make sure we got the min required args */
  185.       usage();          /* host, userid, rest defaults are taken  */
  186.    } /* endif */
  187.  
  188.  
  189.    /* Get local host current dir info */
  190.    curpath = _fullpath(NULL, ".", 0);
  191.  
  192.    /* Setup Local Directory: change to correct disk & path  */
  193.    if (locpath[0] =='\0')
  194.       strncpy(locpath, curpath, MAX_FILENAME_LEN);
  195.    else {
  196.  
  197.  
  198. #ifndef __WATCOMC__                  /* DRC02 - let chdir also change drives */
  199.  
  200.       if (locpath[1] == ':') {                    /* Drive letter specified */
  201.          _chdrive(locpath[0]-'A'+1);              /* Need to change to it   */
  202.       } /* endif */
  203.  
  204. #endif                              /* DRC02 */
  205.  
  206.  
  207.       if (_chdir(locpath)) {             /* Change to the proper local path */
  208.          if (willput) {
  209.             printf("local directory \"%s\" not found\n", locpath);
  210.             exit(1);
  211.          } else {
  212.             if (_mkdir(locpath) == 0) {
  213.                if (_chdir(locpath))
  214.                   printf("Could not CD to newly created dir %s\n", locpath);
  215.             } else {
  216.                printf("could not create local dir %s\n",locpath);
  217.                exit(-1);
  218.             }/*endif*/
  219.          }/*endelse*/
  220.       }/*endif*/
  221.    } /* endelse */
  222.  
  223.  
  224.    /* Get Server System Type */
  225.    if (!ftpsys(host,user,passwd, accnt, host_sys_buf, MAX_FILENAME_LEN+1)) {
  226.       printf("Host type: %s\n", host_sys_buf);
  227.    } else
  228.       switch (ftperrno) {           /*  Exit if the RC is bad */
  229.          case FTPSERVICE:
  230.          case FTPHOST:
  231.          case FTPSOCKET:
  232.          case FTPCONNECT:
  233.          case FTPLOGIN:
  234.             ftperror(ftperrno);
  235.             exit(-1);
  236.             break;
  237.       } /* endswitch */
  238.  
  239.  
  240.    /* See if the dest path is valid on the remote host */
  241.    if (destpath[0] != '\0') {               /* user wants default directory */
  242.       if ((rc = ftpcd(host, user, passwd, accnt, destpath)) != 0) {
  243.          if (rc == FTPLOGIN) {
  244.             ftperror(ftperrno);
  245.             exit(-1);
  246.          } /* endif */
  247.  
  248.  
  249.          if (!willput) {
  250.             printf("Remote directory %s doesn't exist.\n", destpath);
  251.             exit(-1);
  252.          } /*endif*/
  253.  
  254.          /* Directory didn't exist for PUT, try to create */
  255.          if ((rc = ftpmkd(host, user, passwd, accnt, destpath)) == 0) {
  256.             if ((rc = ftpcd(host, user, passwd, accnt, destpath)) == -1) {
  257.                printf("Unable to change directory to %s.\n", destpath);
  258.                exit(-1);
  259.             }/*endif*/
  260.          } else {
  261.             printf(" Unable to create directory \"%s\".\n", destpath);
  262.             exit(-1);
  263.          }/*endelse*/
  264.       }/*endif*/
  265.    } /* endif */
  266.  
  267.    /* Increase filehandles for this appl. */
  268.    if (!DosSetRelMaxFH(&reqcount, &curmaxfh)) {  /* Already > what we want? */
  269.       if (curmaxfh <MAX_FILEHANDLES) {
  270.          if ((apirc = DosSetMaxFH(MAX_FILEHANDLES)) != 0)/*No, set it higher*/
  271.             printf("unable to set max of file handles RC:%d\n", apirc);
  272.       } /* endif */
  273.    } /* endif */
  274.  
  275.    if ((apirc = DosSetMaxFH(MAX_FILEHANDLES)) != 0) {
  276.       printf("unable to set max of file handles RC:%d\n", apirc);
  277.       exit(1);
  278.    }/*endif*/
  279.  
  280.    if (willput)
  281.       sendfiles(NULL);
  282.    else
  283.       getfiles();
  284.  
  285.    ftplogoff();
  286.    return(0);
  287. }/*endmain*/
  288.  
  289.  
  290. /****************************************************************************/
  291. /** Function: sendfiles()                                                  **/
  292. /** Purpose : FTP files from to remote host from local host                **/
  293. /****************************************************************************/
  294. int sendfiles(char *pat) {
  295.    int rc, i;    /* BSF Removed global i.  Not sure if this is a problem */
  296.    ULONG count;
  297.    char *sp;
  298.    HDIR hdir;
  299.    FILEFINDBUF3 f;
  300.    ULONG fileattrib = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM |
  301.                       FILE_DIRECTORY | FILE_ARCHIVED;
  302.  
  303.   if (pat != NULL)
  304.      sp = pat;
  305.    else sp = "*.*";
  306.  
  307.    hdir = 0xffff;                     /* causes a new handle to be returned */
  308.    count = 1;                         /* find the first file */
  309.  
  310.    if ((rc = DosFindFirst(sp, &hdir, fileattrib, &f, sizeof(f), &count,
  311.                      FIL_STANDARD)) != 0)
  312.       return(-1);
  313.  
  314.    _getcwd(out, MAX_FILENAME_LEN+1);
  315.    printf("\nlocal directory %s\n",out);
  316.    i = strlen(out)-1;
  317.  
  318.    if(out[i] == '\\')
  319.       out[i] = '\0';
  320.  
  321.    do {
  322.       if (strcmp(f.achName,".") == 0)
  323.        goto getnext;
  324.  
  325.       if (strcmp(f.achName,"..") == 0)
  326.          goto getnext;
  327.  
  328.       /* Next directory */
  329.       if (f.attrFile & FILE_DIRECTORY) {
  330.          _chdir(f.achName);
  331.  
  332.          /* create the directory if it doesn't exist */
  333.          if ((rc = ftpcd(host, user, passwd, accnt, f.achName)) != 0) {
  334.             if (!ftpmkd(host, user, passwd, accnt, f.achName))
  335.                rc = ftpcd(host, user, passwd, accnt, f.achName);
  336.          }/*endif*/
  337.  
  338.          if (rc == -1) {
  339.             ftperror(rc);
  340.             printf(" Unable to transfer directory %s\n", f.achName);
  341.             goto getnext;
  342.          }/*endif*/
  343.  
  344.          sendfiles(NULL);
  345.          _chdir("..");
  346.          ftpcd(host, user, passwd, accnt, "..");
  347.          _getcwd(out, MAX_FILENAME_LEN);
  348.       } else {
  349.           sprintf(local, "%s\\%s", out, f.achName);
  350.  
  351.           /*  while((p=strchr(local,'\\'))!=NULL) *p='/';*/
  352.         printf("sending %s\n", local);
  353.  
  354.           if (ftpput(host, user, passwd, accnt, local,
  355.                      f.achName, transfertype)) {
  356.            printf("Transfer failed.\n");
  357.              ftperror(ftperrno);
  358.           }
  359.       }/*endelse*/
  360.  
  361. getnext:
  362.    rc = DosFindNext( hdir, &f, sizeof(f), &count);
  363.  
  364.    } while (count && (rc == 0));
  365.  
  366.    DosFindClose(hdir);
  367.    return(0);
  368. }/*endfunction*/
  369.  
  370.  
  371. /****************************************************************************/
  372. /** Function: getfiles()                                                   **/
  373. /** Purpose : FTP files from remote host to local host.                    **/
  374. /****************************************************************************/
  375. void getfiles(void) {
  376.    CHAR tmp[MAX_FILENAME_LEN+1];            /* DRC03 UCHAR->CHAR */
  377.    FILE   *fps;
  378.    int    rc;
  379.    char in[MAX_FILENAME_LEN+1];
  380.    char out[MAX_FILENAME_LEN+1];
  381.    ULONG ActionTaken = 1L;
  382.    char *p;
  383.  
  384.    _getcwd(out, MAX_FILENAME_LEN+1);
  385.    printf("Local directory = %s\n", out);
  386.  
  387.    strcpy(tmp,"XXXXXX");                       /* Don't want tmp to be NULL */
  388.    if (tmpnam(tmp) == NULL) {
  389.       printf("Unable to create unique local file\n");
  390.       exit(1);
  391.    }/*endif*/
  392.  
  393.  
  394.    /*  Non-IBM DOS Server, LS will return files & directories */
  395.    /*  If GET fails, see if it is a directory.                */
  396.    /*   AIX & SUN tested (checked for structure 1/2/95bsf     */
  397.    /*   VM doesn't have DIR's so should be okay               */
  398.    if ((rc = ftpls(host, user, passwd, accnt, tmp, "*")) != 0) {
  399.       printf("Unable to get directory info.\n");
  400.       ftperror(ftperrno);
  401.       exit(1);
  402.    }/*endif*/
  403.  
  404.    if ((fps = fopen(tmp, "r")) == NULL) {
  405.       printf("Unable to open temp file.  RC: %d\n",rc);
  406.       return;
  407.    }/*endif*/
  408.  
  409.  
  410.    while (mygets(in, MAX_FILENAME_LEN+1, fps)) {
  411.       p = &in[0];
  412.  
  413.       /* Make sure this isn't THIS directory name, need to make sure that   */
  414.       /* this does not cause problems for filenames that begin with ".".    */
  415.       if (*p == '.')
  416.        continue;
  417.  
  418.       if (ftpget(host, user, passwd, accnt, p, p, "w", transfertype)) {
  419.        if (p[strlen(p)-1] == ':')
  420.           p[strlen(p)-1] = '\0';
  421.  
  422.        if (!ftpcd(host, user, passwd, accnt, p)) {
  423.           if (_chdir(p) !=0 ) {
  424.              if (_mkdir(p) == 0) {
  425.               if (_chdir(p))
  426.                  printf("Could not CD to newly created dir %s\n", p);
  427.              }
  428.              else
  429.               printf("Could not create local dir %s\n",p);
  430.           }/*endif*/
  431.  
  432.           if (rc != 0)
  433.              ftpcd(host, user, passwd, accnt, "..");
  434.           else {
  435.              getfiles();
  436.              _chdir("..");
  437.              ftpcd(host, user, passwd, accnt, "..");
  438.           }/*endelse*/
  439.        } else
  440.            printf("Remote %s not a file or a dir\n", p);
  441.       } else
  442.        printf("Received %s\\%s\n",out, p);
  443.    }/*endwhile*/
  444.  
  445.    fclose(fps);
  446.    _unlink(tmp);
  447. }/*endfunction*/
  448.  
  449.  
  450. /****************************************************************************/
  451. /** FUNCTION: mygets()                                                     **/
  452. /** PURPOSE : Read line from file and return valid filename.  Return 1 if  **/
  453. /**           a non-blank line is read, otherwise, return 0.               **/
  454. /**           If a directory is encountered, then read all lines until     **/
  455. /**           hitting another blank line or EOF.                           **/
  456. /****************************************************************************/
  457. int mygets(char in[], int len, FILE *fps) {
  458.    int   i = 0;
  459.    CHAR tmp[MAX_FILENAME_LEN+1];                  /* DRC03 UCHAR->CHAR */
  460.  
  461.    for (;;) {
  462.       if (fgets(in, len, fps) == NULL) {
  463.        if (!feof(fps))
  464.           printf("Error reading from temp file.\n");
  465.        in[0] = '\0';        /* EOF, return to calling function.           */
  466.        return (0);
  467.       } /*endif*/
  468.  
  469.       i = strlen(in) - 1;
  470.  
  471.       if (i != 0)             /* Probably read a blank line, read next line */
  472.        break;
  473.    }
  474.  
  475.    in[i] = '\0';
  476.  
  477.    if (in[i-1] == ':') {      /* Found a subdirectory, read thru the lines  */
  478.       for (;;) {              /* after it until hitting a blank line.       */
  479.        if (fgets(tmp, len, fps) == NULL) {
  480.           if (!feof(fps))
  481.              printf("Error reading from temp file.\n");
  482.           break;
  483.        }
  484.          if (strlen(tmp) == 1)                          /* Hit a blank line */
  485.             break;
  486.       } /* endfor */
  487.    }
  488.  
  489.  
  490.    if (i > 0)
  491.       return(1);
  492.    else
  493.       return(0);
  494. }/*endfunction*/
  495.  
  496.  
  497. /****************************************************************************/
  498. /** FUNCTION: usage()                                                      **/
  499. /** PURPOSE:  Display "HELP" menu and exit when complete.                  **/
  500. /****************************************************************************/
  501. void usage(void) {
  502.    printf("Usage:\n");
  503.    printf("RCOPY put|get ascii|binary [-l<local path>] -h<host> -u<userid> -p<password> [-r<rem path>] [-a<account>]\n\n");
  504.    printf("RCOPY transfers the whole directory tree of files.  RCOPY doesn't read userid\n");
  505.    printf("or password from the NETRC file so they must be specified if required.\n");
  506.    printf("\tput  transfers from local host to remote host (default).\n");
  507.    printf("\tget  transfers from remote host to local host.\n");
  508.    printf("\tbinary  Binary transfer mode (default).\n");
  509.    printf("\tascii   ASCII transfer mode.\n");
  510.    printf("\nExample:\n");
  511.    printf("rcopy put -ld:\\tmp -holeg -uyozzo -pyozzops -rc:\\newtmp\n\n");
  512.    printf("Where:\n");
  513.    printf("      d:\\tmp  is a local path to transfer\n");
  514.    printf("      oleg     is a remote host\n");
  515.    printf("      yozzo    is a remote user id\n");
  516.    printf("      yozzops  is a remote password\n");
  517.    exit(1);
  518. }/*endfunction*/
  519.  
  520.  
  521. /****************************************************************************/
  522. /** FUNCTION: ftperror()                                                   **/
  523. /** PURPOSE : translate ftp error rc to text output.                       **/
  524. /****************************************************************************/
  525. void ftperror(int value) {
  526.  
  527.    switch (value) {
  528.  
  529.       case FTPSERVICE:
  530.          printf(" unknown service\n");
  531.          break;
  532.       case FTPHOST:
  533.          printf(" unknown host\n");
  534.          break;
  535.       case FTPSOCKET:
  536.          printf(" unable to obtain socket\n");
  537.          break;
  538.       case FTPCONNECT:
  539.          printf(" unable to connect to server \n");
  540.          break;
  541.       case FTPLOGIN:
  542.          printf(" login failed \n");
  543.          break;
  544.       case FTPABORT:
  545.          printf(" transfer aborted \n");
  546.          break;
  547.       case FTPLOCALFILE:
  548.          printf(" problem openning local file \n");
  549.          break;
  550.       case FTPDATACONN:
  551.          printf(" problem initializing data connection \n");
  552.          break;
  553.       case FTPCOMMAND:
  554.          printf(" command failed \n");
  555.          break;
  556.       case FTPPROXYTHIRD:
  557.          printf(" proxy server does not support third party transfers \n");
  558.          break;
  559.       case FTPNOPRIMARY:
  560.          printf(" No primary connection for proxy transfer \n");
  561.          break;
  562.       case FTPNOXLATETBL:
  563.          printf(" No code page translation table was loded \n");
  564.          break;
  565.    } /* endswitch */
  566. }/*endfunction*/
  567.  
  568.