home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Networking / ncftp-2.4.2-MIHS / src / Put.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-18  |  4.8 KB  |  249 lines

  1. /* Put.c */
  2.  
  3. #include "Sys.h"
  4.  
  5. #include <signal.h>
  6.  
  7. #include "Util.h"
  8. #include "RCmd.h"
  9. #include "Xfer.h"
  10. #include "Cmds.h"
  11. #include "Get.h"
  12. #include "Getopt.h"
  13. #include "Glob.h"
  14. #include "Put.h"
  15.  
  16. extern int gTransferType;
  17. extern int gOptInd, gXferAbortFlag;
  18.  
  19. int
  20. BinaryPut(char *remoteName, int infile, char *localName, long size)
  21. {
  22.     int result;
  23.     XferSpecPtr xp;
  24.  
  25.     /* We don't do a SETBINARY here. Instead, we set it to gTransferType,
  26.      * which we know is not ascii.  Most often this will mean binary mode,
  27.      * but perhaps we're dealing with a tenex machine.
  28.      */
  29.     SetType(gTransferType);
  30.  
  31.     /* Setup the parameter block to give to RDataCmd. */
  32.     xp = InitXferSpec();
  33.     xp->netMode = kNetWriting;
  34.     xp->xProc = StdFileSend;
  35.     xp->inStream = infile;
  36.     /* xp->outStream = gDataSocket;  RDataCmd fills this in when it gets it. */
  37.     
  38.     /* This group is needed for the progress reporting and logging stuff.
  39.      * Otherwise, it isn't that important.
  40.      */
  41.     xp->doReports = (size > 0) ? 1 : 0;
  42.     xp->localFileName = localName;
  43.     xp->remoteFileName = remoteName;
  44.     xp->expectedSize = size;
  45.     
  46.     result = RDataCmd(xp, "STOR %s", remoteName);
  47.     DoneWithXferSpec(xp);
  48.  
  49.     return (result);
  50. }    /* BinaryPut */
  51.  
  52.  
  53.  
  54.  
  55. int AsciiPut(char *remoteName, int infile, char *localName, long size)
  56. {
  57.     int result;
  58.     XferSpecPtr xp;
  59.  
  60.     SETASCII;
  61.     
  62.     /* Setup the parameter block to give to RDataCmd. */
  63.     xp = InitXferSpec();
  64.     xp->netMode = kNetWriting;
  65.     xp->xProc = StdAsciiFileSend;
  66.     xp->inStream = infile;
  67.     /* xp->outStream = gDataSocket;  RDataCmd fills this in when it gets it. */
  68.     
  69.     /* This group is needed for the progress reporting and logging stuff.
  70.      * Otherwise, it isn't that important.
  71.      */
  72.     xp->doReports = (size > 0) ? 1 : 0;
  73.     xp->localFileName = localName;
  74.     xp->remoteFileName = remoteName;
  75.     xp->expectedSize = size;
  76.  
  77.     result = RDataCmd(xp, "STOR %s", remoteName);
  78.     DoneWithXferSpec(xp);
  79.  
  80.     return (result);
  81. }    /* AsciiPut */
  82.  
  83.  
  84.  
  85.  
  86. void GetLocalSendFileName(char *localName, char *remoteName, size_t siz)
  87. {
  88.     char *cp;
  89.     
  90.     /* Create a remote file name.  We want this to be just the same
  91.      * as the local file name, but with the directory path stripped off.
  92.      */ 
  93.     cp = strrchr(localName, '/');
  94.     if (cp == NULL)
  95.         cp = localName;
  96.     else
  97.         cp++;
  98.     
  99.     Strncpy(remoteName, cp, siz);
  100. }    /* GetLocalSendFileName */
  101.  
  102.  
  103.  
  104.  
  105. int OpenLocalSendFile(char *localName, long *size)
  106. {
  107.     int fd;
  108.     struct stat st;
  109.     
  110.     *size = kSizeUnknown;
  111.  
  112.     if ((fd = open(localName, O_RDONLY)) < 0) {
  113.         Error(kDoPerror, "Can't open local file %s.\n", localName);
  114.     } else {
  115.         /* While we're here, get the size of the file.  This is useful
  116.          * for the progress reporting functions.
  117.          */
  118.         if (stat(localName, &st) == 0)
  119.             *size = st.st_size;
  120.     }
  121.     return fd;
  122. }    /* OpenLocalSendFile */
  123.  
  124.  
  125.  
  126.  
  127. int PutCmd(int argc, char **argv)
  128. {
  129.     int fd;
  130.     int i, result, errs, opt;
  131.     string remote;
  132.     long fileSize;
  133.     LineList globFiles;
  134.     LinePtr globFile;
  135.     int renameMode;
  136.  
  137.     errs = 0;
  138.     renameMode = 0;
  139.     GetoptReset();
  140.     while ((opt = Getopt(argc, argv, "Rrz")) >= 0) {
  141.         switch (opt) {
  142.             case 'R':
  143.             case 'r':
  144.                 PrintF("Recursive put not implemented yet.\n");
  145.                 break;
  146.             case 'z':
  147.                 renameMode = 1;
  148.                 break;
  149.             default:
  150.                 return (kUsageErr);
  151.         }
  152.     }
  153.     argv += gOptInd;
  154.     argc -= gOptInd;
  155.  
  156.     if (renameMode) {
  157.         /* User wanted to transfer a local file, but name it different. */
  158.         if (argc < 2)
  159.             return (kUsageErr);
  160.         fd = OpenLocalSendFile(argv[0], &fileSize);
  161.         if (fd < 0) {
  162.             --errs;
  163.         } else {
  164.             if (gTransferType == 'A') {        
  165.                 result = AsciiPut(
  166.                     argv[1],    /* Remote */
  167.                     fd,
  168.                     argv[0],    /* Local */
  169.                     fileSize
  170.                 );
  171.             } else {
  172.                 result = BinaryPut(
  173.                     argv[1],    /* Remote */
  174.                     fd,
  175.                     argv[0],    /* Local */
  176.                     fileSize
  177.                 );
  178.             }
  179.             (void) close(fd);
  180.             if (result < 0) {
  181.                 --errs;
  182.                 /* Maybe remove the remote file. */
  183.             }
  184.         }
  185.     } else for (i=0; i<argc; i++) {
  186.         InitLineList(&globFiles);
  187.         LocalGlob(&globFiles, argv[i]);
  188.         for (globFile = globFiles.first; globFile != NULL;
  189.             globFile = globFile->next)
  190.         {
  191.             GetLocalSendFileName(globFile->line, remote, sizeof(remote));
  192.             fd = OpenLocalSendFile(globFile->line, &fileSize);
  193.             if (fd < 0)
  194.                 continue;
  195.             if (gTransferType == 'A') {        
  196.                 result = AsciiPut(
  197.                     remote,
  198.                     fd,
  199.                     globFile->line,
  200.                     fileSize
  201.                 );
  202.             } else {
  203.                 result = BinaryPut(
  204.                     remote,
  205.                     fd,
  206.                     globFile->line,
  207.                     fileSize
  208.                 );
  209.             }
  210.             (void) close(fd);
  211.             if (result < 0) {
  212.                 --errs;
  213.                 /* Maybe remove the remote file. */
  214.             }
  215.             if (gXferAbortFlag == SIGINT)
  216.                 break;
  217.         }
  218.         DisposeLineListContents(&globFiles);
  219.     }
  220.  
  221.     return (errs);
  222. }    /* PutCmd */
  223.  
  224.  
  225.  
  226.  
  227. int CreateCmd(int argcUNUSED, char **argv)
  228. {
  229.     int fd;
  230.     string remote;
  231.     int result;
  232.  
  233.     /* Good ol' /dev/null always returns EOF on reads. */
  234.     fd = open("/dev/null", O_RDONLY);
  235.     if (fd < 0)
  236.         return (kCmdErr);
  237.     
  238.     STRNCPY(remote, argv[1]);
  239.     result = BinaryPut(
  240.         remote,
  241.         fd,
  242.         "/dev/null",
  243.         0L
  244.     );
  245.  
  246.     (void) close(fd);
  247.     return (result);
  248. }    /* CreateCmd */
  249.