PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/ncftp-3.2.5/libncftp/c_utime.c

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