home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / ncftp / older_versions / ncftp-3.2.2-src.tar.bz2 / ncftp-3.2.2-src.tar / ncftp-3.2.2 / libncftp / c_mkdir.c < prev    next >
C/C++ Source or Header  |  2007-07-25  |  5KB  |  226 lines

  1. /* c_mkdir.c
  2.  *
  3.  * Copyright (c) 1996-2005 Mike Gleason, NcFTP Software.
  4.  * All rights reserved.
  5.  *
  6.  */
  7.  
  8. #include "syshdrs.h"
  9. #ifdef PRAGMA_HDRSTOP
  10. #    pragma hdrstop
  11. #endif
  12.  
  13. int
  14. FTPMkdir2(const FTPCIPtr cip, const char *const newDir, const int recurse, const char *const curDir)
  15. {
  16.     int result, result2;
  17.     char *cp, *newTreeStart, *cp2;
  18.     char dir[512];
  19.     char dir2[512];
  20.     char c;
  21.  
  22.     if (cip == NULL)
  23.         return (kErrBadParameter);
  24.     if (strcmp(cip->magic, kLibraryMagic))
  25.         return (kErrBadMagic);
  26.  
  27.     if ((newDir == NULL) || (newDir[0] == '\0')) {
  28.         cip->errNo = kErrInvalidDirParam;
  29.         return (kErrInvalidDirParam);
  30.     }
  31.  
  32.     /* Preserve old working directory. */
  33.     if ((curDir == NULL) || (curDir[0] == '\0')) {
  34.         /* This hack is nice so you can eliminate an
  35.          * unnecessary "PWD" command on the server,
  36.          * since if you already knew what directory
  37.          * you're in.  We want to minimize the number
  38.          * of client-server exchanges when feasible.
  39.          */
  40.         (void) FTPGetCWD(cip, cip->buf, cip->bufSize);
  41.     }
  42.  
  43.     result = FTPChdir(cip, newDir);
  44.     if (result == kNoErr) {
  45.         /* Directory already exists -- but we
  46.          * must now change back to where we were.
  47.          */
  48.         result2 = FTPChdir(cip, ((curDir == NULL) || (curDir[0] == '\0')) ? cip->buf : curDir);
  49.         if (result2 < 0) {
  50.             result = kErrCannotGoToPrevDir;
  51.             cip->errNo = kErrCannotGoToPrevDir;
  52.             return (result);
  53.         }
  54.  
  55.         /* Don't need to create it. */
  56.         return (kNoErr);
  57.     }
  58.  
  59.     if (recurse == kRecursiveNo) {
  60.         result = FTPCmd(cip, "MKD %s", newDir);
  61.         if (result > 0) {
  62.             if (result != 2) {
  63.                 FTPLogError(cip, kDontPerror, "MKD %s failed; [%s]\n", newDir, cip->lastFTPCmdResultStr);
  64.                 result = kErrMKDFailed;
  65.                 cip->errNo = kErrMKDFailed;
  66.                 return (result);
  67.             } else {
  68.                 result = kNoErr;
  69.             }
  70.         }
  71.     } else {
  72.         (void) STRNCPY(dir, newDir);
  73.  
  74.         /* Strip trailing slashes. */
  75.         cp = dir + strlen(dir) - 1;
  76.         for (;;) {
  77.             if (cp <= dir) {
  78.                 if ((newDir == NULL) || (newDir[0] == '\0')) {
  79.                     cip->errNo = kErrInvalidDirParam;
  80.                     result = kErrInvalidDirParam;
  81.                     return (result);
  82.                 }
  83.             }
  84.             if ((*cp != '/') && (*cp != '\\')) {
  85.                 cp[1] = '\0';
  86.                 break;
  87.             }
  88.             --cp;
  89.         }
  90.         (void) STRNCPY(dir2, dir);
  91.  
  92.         if ((strrchr(dir, '/') == dir) || (strrchr(dir, '\\') == dir)) {
  93.             /* Special case "mkdir /subdir" */
  94.             result = FTPCmd(cip, "MKD %s", dir);
  95.             if (result < 0) {
  96.                 return (result);
  97.             }
  98.             if (result != 2) {
  99.                 FTPLogError(cip, kDontPerror, "MKD %s failed; [%s]\n", dir, cip->lastFTPCmdResultStr);
  100.                 result = kErrMKDFailed;
  101.                 cip->errNo = kErrMKDFailed;
  102.                 return (result);
  103.             }
  104.             /* Haven't chdir'ed, don't need to goto goback. */
  105.             return (kNoErr);
  106.         }
  107.  
  108.         for (;;) {
  109.             cp = strrchr(dir, '/');
  110.             if (cp == NULL)
  111.                 cp = strrchr(dir, '\\');
  112.             if (cp == NULL) {
  113.                 cp = dir + strlen(dir) - 1;
  114.                 if (dir[0] == '\0') {
  115.                     result = kErrMKDFailed;
  116.                     cip->errNo = kErrMKDFailed;
  117.                     return (result);
  118.                 }
  119.                 /* Note: below we will refer to cp + 1
  120.                  * which is why we set cp to point to
  121.                  * the byte before the array begins!
  122.                  */
  123.                 cp = dir;
  124.                 --cp;
  125.                 break;
  126.             }
  127.             if (cp == dir) {
  128.                 result = kErrMKDFailed;
  129.                 cip->errNo = kErrMKDFailed;
  130.                 return (result);
  131.             }
  132.             *cp = '\0';
  133.             result = FTPChdir(cip, dir);
  134.             if (result == 0) {
  135.                 break;    /* Found a valid parent dir. */
  136.                 /* from this point, we need to preserve old dir. */
  137.             }
  138.         }
  139.  
  140.         newTreeStart = dir2 + ((cp + 1) - dir);
  141.         for (cp = newTreeStart; ; ) {
  142.             cp2 = cp;
  143.             cp = strchr(cp2, '/');
  144.             c = '/';
  145.             if (cp == NULL)
  146.                 cp = strchr(cp2, '\\');
  147.             if (cp != NULL) {
  148.                 c = *cp;
  149.                 *cp = '\0';
  150.                 if (cp[1] == '\0') {
  151.                     /* Done, if they did "mkdir /tmp/dir/" */
  152.                     break;
  153.                 }
  154.             }
  155.             result = FTPCmd(cip, "MKD %s", newTreeStart);
  156.             if (result < 0) {
  157.                 return (result);
  158.             }
  159.             if (result != 2) {
  160.                 FTPLogError(cip, kDontPerror, "Cwd=%s; MKD %s failed; [%s]\n", cip->buf, newTreeStart, cip->lastFTPCmdResultStr);
  161.                 result = kErrMKDFailed;
  162.                 cip->errNo = kErrMKDFailed;
  163.                 goto goback;
  164.             }
  165.             if (cp == NULL)
  166.                 break;    /* No more to make, done. */
  167.             *cp++ = c;
  168.         }
  169.         result = kNoErr;
  170.  
  171. goback:
  172.         result2 = FTPChdir(cip, ((curDir == NULL) || (curDir[0] == '\0')) ? cip->buf : curDir);
  173.         if ((result == 0) && (result2 < 0)) {
  174.             result = kErrCannotGoToPrevDir;
  175.             cip->errNo = kErrCannotGoToPrevDir;
  176.         }
  177.     }
  178.     return (result);
  179. }    /* FTPMkdir2 */
  180.  
  181.  
  182.  
  183. int
  184. FTPMkdir(const FTPCIPtr cip, const char *const newDir, const int recurse)
  185. {
  186.     return (FTPMkdir2(cip, newDir, recurse, NULL));
  187. }    /* FTPMkdir */
  188.  
  189.  
  190.  
  191.  
  192. int
  193. FTPMkParentDir(const FTPCIPtr cip, const char *const path, const int recurse, const char *const curDir)
  194. {
  195.     char newDir[512];
  196.     char *cp;
  197.  
  198.     if ((path == NULL) || (path[0] == '\0')) {
  199.         cip->errNo = kErrInvalidDirParam;
  200.         return (kErrInvalidDirParam);
  201.     }
  202.  
  203.     STRNCPY(newDir, path);
  204.     if ((newDir[sizeof(newDir) - 2] != '\0') && (path[sizeof(newDir) - 1] != '\0')) {
  205.         /* Path too long to make a copy of it. */
  206.         cip->errNo = kErrInvalidDirParam;
  207.         return (kErrInvalidDirParam);
  208.     }
  209.  
  210.     StrRemoveTrailingSlashes(newDir);
  211.     cp = StrRFindLocalPathDelim(newDir);
  212.     if (cp == newDir) {
  213.         /* File is in the root directory, which is already made. */
  214.         return (kNoErr);
  215.     } else if (cp == NULL) {
  216.         /* File is in the current directory; the parent directory
  217.          * is already made.
  218.          */
  219.         return (kNoErr);
  220.     }
  221.     *cp = '\0';
  222.  
  223.     return (FTPMkdir2(cip, newDir, recurse, curDir));
  224. }    /* FTPMkParentDir */
  225.  
  226.