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_utime.c < prev    next >
C/C++ Source or Header  |  2008-07-13  |  5KB  |  169 lines

  1. /* c_utime.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. #define _CRT_SECURE_NO_WARNINGS 1
  14.  
  15. static void
  16. GmTimeStr(char *const dst, const size_t dstsize, time_t t)
  17. {
  18.     char buf[64];
  19.     struct tm gt;
  20.  
  21.     if (Gmtime(t, >) == NULL) {
  22.         dst[0] = '\0';
  23.     } else {
  24. #ifdef HAVE_SNPRINTF
  25.         buf[sizeof(buf) - 1] = '\0';
  26.         (void) snprintf(buf, sizeof(buf) - 1, "%04d%02d%02d%02d%02d%02d",
  27. #else
  28.         (void) sprintf(buf, "%04d%02d%02d%02d%02d%02d",
  29. #endif
  30.             gt.tm_year + 1900,
  31.             gt.tm_mon + 1,
  32.             gt.tm_mday,
  33.             gt.tm_hour,
  34.             gt.tm_min,
  35.             gt.tm_sec
  36.         );
  37.         (void) Strncpy(dst, buf, dstsize);
  38.     }
  39. }    /* GmTimeStr */
  40.  
  41.  
  42.  
  43.  
  44. int
  45. FTPUtime(const FTPCIPtr cip, const char *const file, time_t actime, time_t modtime, time_t crtime)
  46. {
  47.     char mstr[64], astr[64], cstr[64];
  48.     time_t now;
  49.     int result;
  50.     ResponsePtr rp;
  51.  
  52.     if (cip == NULL)
  53.         return (kErrBadParameter);
  54.     if (strcmp(cip->magic, kLibraryMagic))
  55.         return (kErrBadMagic);
  56.  
  57.     now = (time_t) 0;
  58.     if ((modtime == (time_t) 0) || (modtime == (time_t) -1))
  59.         modtime = time(&now);
  60.     (void) GmTimeStr(mstr, sizeof(mstr), modtime);
  61.  
  62.     result = kErrUTIMENotAvailable;
  63.     if (cip->hasSITE_UTIME != kCommandNotAvailable) {
  64.         if ((actime == (time_t) 0) || (actime == (time_t) -1)) {
  65.             if (now != (time_t) 0) {
  66.                 actime = now;
  67.             } else {
  68.                 actime = time(&now);
  69.             }
  70.         }
  71.         if ((crtime == (time_t) 0) || (crtime == (time_t) -1)) {
  72.             if (now != (time_t) 0) {
  73.                 crtime = now;
  74.             } else {
  75.                 crtime = time(&now);
  76.             }
  77.         }
  78.         (void) GmTimeStr(astr, sizeof(astr), actime);
  79.         (void) GmTimeStr(cstr, sizeof(cstr), crtime);
  80.  
  81.         rp = InitResponse();
  82.         if (rp == NULL) {
  83.             result = kErrMallocFailed;
  84.             cip->errNo = kErrMallocFailed;
  85.             FTPLogError(cip, kDontPerror, "Malloc failed.\n");
  86.         } else {
  87.             result = RCmd(cip, rp, "SITE UTIME %s %s %s %s UTC", file, astr, mstr, cstr);     
  88.             if (result < 0) {
  89.                 DoneWithResponse(cip, rp);
  90.                 return (result);
  91.             } else if (result == 2) {
  92.                 cip->hasSITE_UTIME = kCommandAvailable;
  93.                 result = kNoErr;
  94.                 DoneWithResponse(cip, rp);
  95.             } else if ((FTP_UNIMPLEMENTED_CMD(rp->code)) || (FTP_SYNTAX_ERROR_IN_PARAMETERS(rp->code))) {
  96.                 cip->hasSITE_UTIME = kCommandNotAvailable;
  97.                 cip->errNo = kErrUTIMENotAvailable;
  98.                 result = kErrUTIMENotAvailable;
  99.                 DoneWithResponse(cip, rp);
  100.             } else if ((cip->serverType == kServerTypeNcFTPd) && (strchr(file, ' ') != NULL)) {
  101.                 /* Workaround bug with filenames containing
  102.                  * spaces.
  103.                  */
  104.                 DoneWithResponse(cip, rp);
  105.                 result = FTPCmd(cip, "MDTM %s %s", mstr, file);     
  106.                 if ((result == 2) || (result == 0)) {
  107.                     result = kNoErr;
  108.                 } else {
  109.                     cip->errNo = kErrUTIMEFailed;
  110.                     result = kErrUTIMEFailed;
  111.                 }
  112.             } else {
  113.                 cip->errNo = kErrUTIMEFailed;
  114.                 result = kErrUTIMEFailed;
  115.                 DoneWithResponse(cip, rp);
  116.             }
  117.         }
  118.     }
  119.     if (result == kErrUTIMENotAvailable) {
  120.         if ((cip->hasMDTM == kCommandNotAvailable) || (cip->hasMDTM_set == kCommandNotAvailable)) {
  121.             cip->errNo = kErrUTIMENotAvailable;
  122.             result = kErrUTIMENotAvailable;
  123.         } else {
  124.             rp = InitResponse();
  125.             if (rp == NULL) {
  126.                 result = kErrMallocFailed;
  127.                 cip->errNo = kErrMallocFailed;
  128.                 FTPLogError(cip, kDontPerror, "Malloc failed.\n");
  129.             } else {
  130.                 result = RCmd(cip, rp, "MDTM %s %s", mstr, file);     
  131.                 if (result < 0) {
  132.                     DoneWithResponse(cip, rp);
  133.                     return (result);
  134.                 } else if (result == 2) {
  135.                     cip->hasMDTM_set = kCommandAvailable;
  136.                     result = kNoErr;
  137.                 } else {
  138.                     /* Ideally, we would only disable
  139.                      * the MDTM_set feature if we
  140.                      * received a code that corresponds
  141.                      * to an unimplemented command.
  142.                      * Unfortunately, since the regular
  143.                      * syntax of MDTM uses a pathname
  144.                      * parameter, we'll often get back
  145.                      * a 550 response when we try to
  146.                      * set the timestamp, because a
  147.                      * server that doesn't support this
  148.                      * feature reads the timestamp
  149.                      * as a pathname which doesn't
  150.                      * exist.  As a result, this feature
  151.                      * could get disabled if a server
  152.                      * which does support the feature
  153.                      * returns a 550 when it turns
  154.                      * out that the file exists but
  155.                      * we didn't have permission to
  156.                      * change the timestamp.
  157.                      */
  158.                     if ((FTP_UNIMPLEMENTED_CMD(rp->code)) || (FTP_SYNTAX_ERROR_IN_PARAMETERS(rp->code)) || (rp->code == 550))
  159.                         cip->hasMDTM_set = kCommandNotAvailable;
  160.                     cip->errNo = kErrUTIMENotAvailable;
  161.                     result = kErrUTIMENotAvailable;
  162.                 }
  163.                 DoneWithResponse(cip, rp);
  164.             }
  165.         }
  166.     }
  167.     return (result);
  168. }    /* FTPUtime */
  169.