PageRenderTime 27ms CodeModel.GetById 14ms app.highlight 11ms 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
  8#include "syshdrs.h"
  9#ifdef PRAGMA_HDRSTOP
 10#	pragma hdrstop
 11#endif
 12
 13#define _CRT_SECURE_NO_WARNINGS 1
 14
 15static void
 16GmTimeStr(char *const dst, const size_t dstsize, time_t t)
 17{
 18	char buf[64];
 19	struct tm gt;
 20
 21	if (Gmtime(t, &gt) == 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
 44int
 45FTPUtime(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 = kNoErr;
 50	int wantToSetCrTime = 1;
 51	ResponsePtr rp;
 52
 53	if (cip == NULL)
 54		return (kErrBadParameter);
 55	if (strcmp(cip->magic, kLibraryMagic))
 56		return (kErrBadMagic);
 57
 58	now = (time_t) 0;
 59	if ((modtime == (time_t) 0) || (modtime == (time_t) -1))
 60		modtime = time(&now);
 61	(void) GmTimeStr(mstr, sizeof(mstr), modtime);
 62
 63	if ((actime == (time_t) 0) || (actime == (time_t) -1)) {
 64		if (now != (time_t) 0) {
 65			actime = now;
 66		} else {
 67			actime = time(&now);
 68		}
 69	}
 70	if ((crtime == (time_t) 0) || (crtime == (time_t) -1)) {
 71		wantToSetCrTime = 0;
 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	if ((cip->hasMFF == kCommandAvailable) && (wantToSetCrTime != 0)) {
 82		result = FTPCmd(cip, "MFF Modify=%s;Create=%s %s", mstr, cstr, file); 	
 83		if ((result == 2) || (result == 0)) {
 84			result = kNoErr;
 85			return (result);
 86		} else {
 87			cip->errNo = kErrUTIMEFailed;
 88			result = kErrUTIMEFailed;
 89			/* It may not have liked us trying to set the creation time.
 90			 * Fallthrough and try just setting the modification time.
 91			 */
 92		}
 93	}
 94
 95	if (cip->hasMFMT == kCommandAvailable) {
 96		result = FTPCmd(cip, "MFMT %s %s", mstr, file); 	
 97		if ((result == 2) || (result == 0)) {
 98			result = kNoErr;
 99		} else {
100			cip->errNo = kErrUTIMEFailed;
101			result = kErrUTIMEFailed;
102		}
103		return (result);
104	}
105
106	if (result == kNoErr)
107		result = kErrUTIMENotAvailable;
108	if (cip->hasSITE_UTIME != kCommandNotAvailable) {
109		rp = InitResponse();
110		if (rp == NULL) {
111			result = kErrMallocFailed;
112			cip->errNo = kErrMallocFailed;
113			FTPLogError(cip, kDontPerror, "Malloc failed.\n");
114		} else {
115			result = RCmd(cip, rp, "SITE UTIME %s %s %s %s UTC", file, astr, mstr, cstr); 	
116			if (result < 0) {
117				DoneWithResponse(cip, rp);
118				return (result);
119			} else if (result == 2) {
120				cip->hasSITE_UTIME = kCommandAvailable;
121				result = kNoErr;
122				DoneWithResponse(cip, rp);
123			} else if ((FTP_UNIMPLEMENTED_CMD(rp->code)) || (FTP_SYNTAX_ERROR_IN_PARAMETERS(rp->code))) {
124				cip->hasSITE_UTIME = kCommandNotAvailable;
125				cip->errNo = kErrUTIMENotAvailable;
126				result = kErrUTIMENotAvailable;
127				DoneWithResponse(cip, rp);
128			} else if ((cip->serverType == kServerTypeNcFTPd) && (strchr(file, ' ') != NULL)) {
129				/* Workaround bug with filenames containing
130				 * spaces.
131				 */
132				DoneWithResponse(cip, rp);
133				result = FTPCmd(cip, "MDTM %s %s", mstr, file); 	
134				if ((result == 2) || (result == 0)) {
135					result = kNoErr;
136				} else {
137					cip->errNo = kErrUTIMEFailed;
138					result = kErrUTIMEFailed;
139				}
140			} else {
141				cip->errNo = kErrUTIMEFailed;
142				result = kErrUTIMEFailed;
143				DoneWithResponse(cip, rp);
144			}
145		}
146	}
147	if (result == kErrUTIMENotAvailable) {
148		if ((cip->hasMDTM == kCommandNotAvailable) || (cip->hasMDTM_set == kCommandNotAvailable)) {
149			cip->errNo = kErrUTIMENotAvailable;
150			result = kErrUTIMENotAvailable;
151		} else {
152			rp = InitResponse();
153			if (rp == NULL) {
154				result = kErrMallocFailed;
155				cip->errNo = kErrMallocFailed;
156				FTPLogError(cip, kDontPerror, "Malloc failed.\n");
157			} else {
158				result = RCmd(cip, rp, "MDTM %s %s", mstr, file); 	
159				if (result < 0) {
160					DoneWithResponse(cip, rp);
161					return (result);
162				} else if (result == 2) {
163					cip->hasMDTM_set = kCommandAvailable;
164					result = kNoErr;
165				} else {
166					/* Ideally, we would only disable
167					 * the MDTM_set feature if we
168					 * received a code that corresponds
169					 * to an unimplemented command.
170					 * Unfortunately, since the regular
171					 * syntax of MDTM uses a pathname
172					 * parameter, we'll often get back
173					 * a 550 response when we try to
174					 * set the timestamp, because a
175					 * server that doesn't support this
176					 * feature reads the timestamp
177					 * as a pathname which doesn't
178					 * exist.  As a result, this feature
179					 * could get disabled if a server
180					 * which does support the feature
181					 * returns a 550 when it turns
182					 * out that the file exists but
183					 * we didn't have permission to
184					 * change the timestamp.
185					 */
186					if ((FTP_UNIMPLEMENTED_CMD(rp->code)) || (FTP_SYNTAX_ERROR_IN_PARAMETERS(rp->code)) || (rp->code == 550))
187						cip->hasMDTM_set = kCommandNotAvailable;
188					cip->errNo = kErrUTIMENotAvailable;
189					result = kErrUTIMENotAvailable;
190				}
191				DoneWithResponse(cip, rp);
192			}
193		}
194	}
195	return (result);
196}	/* FTPUtime */