ObjFW  Check-in [ba57490ba6]

Overview
Comment:+[copyFileAtPath:toPath:]: Never override items.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ba57490ba604d42309f4c07e28d10d8dbcfcafce574062a119ec15c63ebeddc1
User & Date: js on 2013-12-11 22:19:40
Other Links: manifest | tags
Context
2013-12-11
22:26
+[{copy,rename}ItemAtPath...]: Require full path. check-in: 242fd56445 user: js tags: trunk
22:19
+[copyFileAtPath:toPath:]: Never override items. check-in: ba57490ba6 user: js tags: trunk
2013-12-10
17:26
Prevent entering directories twice. check-in: 0320eee453 user: js tags: trunk
Changes

Modified src/OFFile.h from [78ef5184a3] to [4cbfda525d].

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
			  permissions: (mode_t)permissions;
#endif

#ifdef OF_HAVE_CHOWN
/*!
 * @brief Changes the owner of an item.
 *
 * This method is not available on Windows.
 *
 * @param path The path to the item whose owner should be changed
 * @param owner The new owner for the item
 * @param group The new group for the item
 */
+ (void)changeOwnerOfItemAtPath: (OFString*)path
			  owner: (OFString*)owner
			  group: (OFString*)group;
#endif

/*!
 * @brief Copies a file, directory or symlink (if supported by the OS).
 *
 * If an item already exists, it is replaced. This is also the case if a
 * directory is copied and an item already exists in the destination directory.

 *
 * @param source The file, directory or symlink to copy
 * @param destination The destination path
 */
+ (void)copyItemAtPath: (OFString*)source
		toPath: (OFString*)destination;








|













|
|
>







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
			  permissions: (mode_t)permissions;
#endif

#ifdef OF_HAVE_CHOWN
/*!
 * @brief Changes the owner of an item.
 *
 * This method is not available on some systems, most notably Windows.
 *
 * @param path The path to the item whose owner should be changed
 * @param owner The new owner for the item
 * @param group The new group for the item
 */
+ (void)changeOwnerOfItemAtPath: (OFString*)path
			  owner: (OFString*)owner
			  group: (OFString*)group;
#endif

/*!
 * @brief Copies a file, directory or symlink (if supported by the OS).
 *
 * If an item already exists, the copy operation fails. This is also the case
 * if a directory is copied and an item already exists in the destination
 * directory.
 *
 * @param source The file, directory or symlink to copy
 * @param destination The destination path
 */
+ (void)copyItemAtPath: (OFString*)source
		toPath: (OFString*)destination;

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
 */
+ (void)removeItemAtPath: (OFString*)path;

#ifdef OF_HAVE_LINK
/*!
 * @brief Creates a hard link for the specified item.
 *
 * Not available on Windows.
 *
 * @param source The path of the item for which a link should be created
 * @param destination The path of the item which should link to the source
 */
+ (void)linkItemAtPath: (OFString*)source
		toPath: (OFString*)destination;
#endif

#ifdef OF_HAVE_SYMLINK
/*!
 * @brief Creates a symbolic link for an item.
 *
 * Not available on Windows.
 *
 * @param destination The path of the item which should symbolically link to the
 *		      source
 * @param source The path of the item for which a symbolic link should be
 *		 created
 */
+ (void)createSymbolicLinkAtPath: (OFString*)destination







|












|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
 */
+ (void)removeItemAtPath: (OFString*)path;

#ifdef OF_HAVE_LINK
/*!
 * @brief Creates a hard link for the specified item.
 *
 * This method is not available on some systems, most notably Windows.
 *
 * @param source The path of the item for which a link should be created
 * @param destination The path of the item which should link to the source
 */
+ (void)linkItemAtPath: (OFString*)source
		toPath: (OFString*)destination;
#endif

#ifdef OF_HAVE_SYMLINK
/*!
 * @brief Creates a symbolic link for an item.
 *
 * This method is not available on some systems, most notably Windows.
 *
 * @param destination The path of the item which should symbolically link to the
 *		      source
 * @param source The path of the item for which a symbolic link should be
 *		 created
 */
+ (void)createSymbolicLinkAtPath: (OFString*)destination

Modified src/OFFile.m from [4da01770ca] to [d5e09aa3e8].

546
547
548
549
550
551
552












553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	pool = objc_autoreleasePoolPush();

	if ([self directoryExistsAtPath: destination]) {
		OFArray *components = [OFArray arrayWithObjects:
		    destination, [source lastPathComponent], nil];
		destination = [OFString pathWithComponents: components];
	}













#ifndef _WIN32
	if (lstat([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s))
#else
	if (_wstat([source UTF16String], &s))
#endif
		@throw [OFCopyItemFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination];

	if (S_ISREG(s.st_mode)) {
#ifdef OF_HAVE_CHMOD
		bool override = [self fileExistsAtPath: destination];
#endif
		size_t pageSize = [OFSystemInfo pageSize];
		OFFile *sourceFile = nil;
		OFFile *destinationFile = nil;
		char *buffer;

		if ((buffer = malloc(pageSize)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: pageSize];

		@try {
#ifdef OF_HAVE_SYMLINK
			if ([OFFile symbolicLinkExistsAtPath: destination])
				[OFFile removeItemAtPath: destination];
#endif

			sourceFile = [OFFile fileWithPath: source
						     mode: @"rb"];
			destinationFile = [OFFile fileWithPath: destination
							  mode: @"wb"];

			while (![sourceFile isAtEndOfStream]) {
				size_t length;

				length = [sourceFile readIntoBuffer: buffer
							     length: pageSize];
				[destinationFile writeBuffer: buffer
						      length: length];
			}

#ifdef OF_HAVE_CHMOD
			if (!override)
				[self changePermissionsOfItemAtPath: destination
							permissions: s.st_mode];
#endif
		} @catch (id e) {
			@throw [OFCopyItemFailedException
			    exceptionWithSourcePath: source
				    destinationPath: destination];
		} @finally {
			[sourceFile close];
			[destinationFile close];
			free(buffer);
		}
	} else if (S_ISDIR(s.st_mode)) {
		OFArray *contents;
		OFEnumerator *enumerator;
		OFString *item;

		@try {
			if (![OFFile directoryExistsAtPath: destination])
				[OFFile createDirectoryAtPath: destination];

#ifdef OF_HAVE_CHMOD
			[OFFile changePermissionsOfItemAtPath: destination
						  permissions: s.st_mode];
#endif

			contents = [OFFile contentsOfDirectoryAtPath: source];
		} @catch (id e) {







>
>
>
>
>
>
>
>
>
>
>
>










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





<
|
<







546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574















































575
576
577
578
579
580

581

582
583
584
585
586
587
588
	pool = objc_autoreleasePoolPush();

	if ([self directoryExistsAtPath: destination]) {
		OFArray *components = [OFArray arrayWithObjects:
		    destination, [source lastPathComponent], nil];
		destination = [OFString pathWithComponents: components];
	}

#ifndef _WIN32
	if (lstat([destination
		cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s) == 0) {
#else
	if (_wstat([destination UTF16String], &s) == 0) {
#endif
		errno = EEXIST;
		@throw [OFCopyItemFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination];
	}

#ifndef _WIN32
	if (lstat([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], &s))
#else
	if (_wstat([source UTF16String], &s))
#endif
		@throw [OFCopyItemFailedException
		    exceptionWithSourcePath: source
			    destinationPath: destination];
















































	if (S_ISDIR(s.st_mode)) {
		OFArray *contents;
		OFEnumerator *enumerator;
		OFString *item;

		@try {

			[OFFile createDirectoryAtPath: destination];

#ifdef OF_HAVE_CHMOD
			[OFFile changePermissionsOfItemAtPath: destination
						  permissions: s.st_mode];
#endif

			contents = [OFFile contentsOfDirectoryAtPath: source];
		} @catch (id e) {
643
644
645
646
647
648
649
650





651



652
653


654












655





656




657



658
659
660
661
662
663
664
			destinationPath = [OFString
			    pathWithComponents: components];

			[OFFile copyItemAtPath: sourcePath
					toPath: destinationPath];

			objc_autoreleasePoolPop(pool2);
		}





#ifdef OF_HAVE_SYMLINK



	} else if (S_ISLNK(s.st_mode)) {
		@try {


			if ([OFFile symbolicLinkExistsAtPath: destination] ||












			    [OFFile fileExistsAtPath: destination])





				[OFFile removeItemAtPath: destination];








			source = [OFFile
			    destinationOfSymbolicLinkAtPath: source];

			[OFFile createSymbolicLinkAtPath: destination
				     withDestinationPath: source];
		} @catch (id e) {
			@throw [OFCopyItemFailedException








>
>
>
>
>
|
>
>
>
|

>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
|
>
>
>







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
			destinationPath = [OFString
			    pathWithComponents: components];

			[OFFile copyItemAtPath: sourcePath
					toPath: destinationPath];

			objc_autoreleasePoolPop(pool2);
		}
	} else if (S_ISREG(s.st_mode)) {
		size_t pageSize = [OFSystemInfo pageSize];
		OFFile *sourceFile = nil;
		OFFile *destinationFile = nil;
		char *buffer;

		if ((buffer = malloc(pageSize)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: pageSize];

		@try {
			sourceFile = [OFFile fileWithPath: source
						     mode: @"rb"];
			destinationFile = [OFFile fileWithPath: destination
							  mode: @"wb"];

			while (![sourceFile isAtEndOfStream]) {
				size_t length;

				length = [sourceFile readIntoBuffer: buffer
							     length: pageSize];
				[destinationFile writeBuffer: buffer
						      length: length];
			}

#ifdef OF_HAVE_CHMOD
			[self changePermissionsOfItemAtPath: destination
						permissions: s.st_mode];
#endif
		} @catch (id e) {
			@throw [OFCopyItemFailedException
			    exceptionWithSourcePath: source
				    destinationPath: destination];
		} @finally {
			[sourceFile close];
			[destinationFile close];
			free(buffer);
		}
#ifdef OF_HAVE_SYMLINK
	} else if (S_ISLNK(s.st_mode)) {
		@try {
			source = [OFFile
			    destinationOfSymbolicLinkAtPath: source];

			[OFFile createSymbolicLinkAtPath: destination
				     withDestinationPath: source];
		} @catch (id e) {
			@throw [OFCopyItemFailedException