ObjFW  Check-in [a4c6c83384]

Overview
Comment:Support for setting extended attributes on Linux
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a4c6c83384aa48c338a01b01c809d1821eea9a6f28e3c272dfc2b32c1f1ce156
User & Date: js on 2023-01-22 22:43:18
Other Links: manifest | tags
Context
2023-01-22
23:01
Support for removing extended attributes on Linux check-in: 5a553951a5 user: js tags: trunk
22:43
Support for setting extended attributes on Linux check-in: a4c6c83384 user: js tags: trunk
21:56
Add missing #import to make GCC happy check-in: 260c9acb96 user: js tags: trunk
Changes

Modified src/OFFileIRIHandler.m from [36e6332bf0] to [8c0c84267e].

1560
1561
1562
1563
1564
1565
1566
























1567
1568
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



	[data retain];

	objc_autoreleasePoolPop(pool);

	return [data autorelease];
}

- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	void *pool = objc_autoreleasePoolPush();
	OFString *path = IRI.fileSystemRepresentation;
	OFStringEncoding encoding = [OFLocale encoding];

	if (lsetxattr([path cStringWithEncoding: encoding],
	    [name cStringWithEncoding: encoding], data.items,
	    data.count * data.itemSize, 0) != 0) {
		int errNo = errno;

		/* TODO: Add an attribute (prefix?) for extended attributes? */
		@throw [OFSetItemAttributesFailedException
		    exceptionWithIRI: IRI
			  attributes: [OFDictionary dictionary]
		     failedAttribute: @""
			       errNo: errNo];
	}

	objc_autoreleasePoolPop(pool);
}
#endif
@end

Modified src/OFFileManager.h from [59114baee3] to [9eaa95b3c2].

682
683
684
685
686
687
688
689

690
691
692
693
694
695


696
697
698


699
700
701
702

703
704
705
706
707
708
709
710
711
712


713
714
715










































716
717
718
719
720
721
722
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698


699
700
701
702
703

704
705
706
707
708
709
710
711
712
713
714
715
716
717


718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766







-
+






+
+

-
-
+
+



-
+










+
+

-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *					 scheme
 */
- (void)createSymbolicLinkAtIRI: (OFIRI *)IRI
	    withDestinationPath: (OFString *)target;

#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
/**
 * @brief Returns the extended attribute with the specified name for the
 * @brief Returns the extended attribute data for the specified name for the
 *	  specified path.
 *
 * @param name The name of the extended attribute
 * @param path The path of the item to return the extended attribute from
 * @throw OFGetItemAttributesFailedException Getting the extended attribute
 *					     failed
 * @throw OFNotImplementedException Getting extended attributes is not
 *				    implemented for the specified item
 */
- (OFData *)extendedAttributeForName: (OFString *)name
			ofItemAtPath: (OFString *)path;
- (OFData *)extendedAttributeDataForName: (OFString *)name
			    ofItemAtPath: (OFString *)path;
#endif

/**
 * @brief Returns the extended attribute with the specified name for the
 * @brief Returns the extended attribute data for the specified name for the
 *	  specified IRI.
 *
 * This method is not available for all IRIs.
 *
 * @param name The name of the extended attribute
 * @param IRI The IRI of the item to return the extended attribute from
 * @throw OFGetItemAttributesFailedException Getting the extended attribute
 *					     failed
 * @throw OFUnsupportedProtocolException No handler is registered for the IRI's
 *					 scheme
 * @throw OFNotImplementedException Getting extended attributes is not
 *				    implemented for the specified item
 */
- (OFData *)extendedAttributeForName: (OFString *)name
			 ofItemAtIRI: (OFIRI *)IRI;
- (OFData *)extendedAttributeDataForName: (OFString *)name
			     ofItemAtIRI: (OFIRI *)IRI;

#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
/**
 * @brief Sets the extended attribute data for the specified name for the
 *	  specified IRI.
 *
 * This method is not available for all IRIS.
 *
 * @param data The data for the extended attribute
 * @param name The name of the extended attribute
 * @param path The path of the item to set the extended attribute on
 * @throw OFSetItemAttributesFailedException Setting the extended attribute
 *					     failed
 * @throw OFNotImplementedException Setting extended attributes is not
 *				    implemented for the specified item
 */
- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		    ofItemAtPath: (OFString *)path;
#endif

/**
 * @brief Sets the extended attribute data for the specified name for the
 *	  specified IRI.
 *
 * This method is not available for all IRIS.
 *
 * @param data The data for the extended attribute
 * @param name The name of the extended attribute
 * @param IRI The IRI of the item to set the extended attribute on
 * @throw OFSetItemAttributesFailedException Setting the extended attribute
 *					     failed
 * @throw OFUnsupportedProtocolException No handler is registered for the IRI's
 *					 scheme
 * @throw OFNotImplementedException Setting extended attributes is not
 *				    implemented for the specified item
 */
- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI;
@end

@interface OFDictionary (FileAttributes)
/**
 * @brief The @ref OFFileSize key from the dictionary.
 *
 * @throw OFUndefinedKeyException The key is missing

Modified src/OFFileManager.m from [5adb6092f8] to [b17fc97839].

195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210







+

-








- (OFIRI *)currentDirectoryIRI
{
	void *pool = objc_autoreleasePoolPush();
	OFIRI *ret;

	ret = [OFIRI fileIRIWithPath: self.currentDirectoryPath];
	ret = [ret retain];

	[ret retain];
	objc_autoreleasePoolPop(pool);
	return [ret autorelease];
}
#endif

- (OFFileAttributes)attributesOfItemAtIRI: (OFIRI *)IRI
{
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
222
223
224
225
226
227
228


229
230
231
232
233
234
235
236







-
-
+







#ifdef OF_HAVE_FILES
- (OFFileAttributes)attributesOfItemAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFFileAttributes ret;

	ret = [self attributesOfItemAtIRI: [OFIRI fileIRIWithPath: path]];

	[ret retain];
	ret = [ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
#endif

452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465







-
+







	IRIs = [self contentsOfDirectoryAtIRI: [OFIRI fileIRIWithPath: path]];
	ret = [OFMutableArray arrayWithCapacity: IRIs.count];

	for (OFIRI *IRI in IRIs)
		[ret addObject: IRI.lastPathComponent];

	[ret makeImmutable];
	[ret retain];
	ret = [ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495







-
+







		else
			[ret addObject: fullSubpath];

		objc_autoreleasePoolPop(pool2);
	}

	[ret makeImmutable];
	[ret retain];
	ret = [ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (void)changeCurrentDirectoryPath: (OFString *)path
886
887
888
889
890
891
892

893


































894
895
896
897
898
899
900
901
902


903

904
905
906

907
908


909
910
911
912
913
914



915
916
917
918
919
920
921
922
923
924
925
926
885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937

938
939
940
941
942


943
944
945
946




947
948
949


950


951
952
953
954
955
956
957







+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









+
+
-
+



+
-
-
+
+


-
-
-
-
+
+
+
-
-

-
-







	void *pool = objc_autoreleasePoolPush();
	[self createSymbolicLinkAtIRI: [OFIRI fileIRIWithPath: path]
		  withDestinationPath: target];
	objc_autoreleasePoolPop(pool);
}
#endif

- (OFData *)extendedAttributeDataForName: (OFString *)name
- (OFData *)extendedAttributeForName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI
			     ofItemAtIRI: (OFIRI *)IRI
{
	OFIRIHandler *IRIHandler;

	if (IRI == nil)
		@throw [OFInvalidArgumentException exception];

	if ((IRIHandler = [OFIRIHandler handlerForIRI: IRI]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithIRI: IRI];

	return [IRIHandler extendedAttributeDataForName: name ofItemAtIRI: IRI];
}

#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
- (OFData *)extendedAttributeDataForName: (OFString *)name
			    ofItemAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFData *ret;

	ret = [self
	    extendedAttributeDataForName: name
			     ofItemAtIRI: [OFIRI fileIRIWithPath: path]];
	ret = [ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
#endif

- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	OFIRIHandler *IRIHandler;

	if (IRI == nil)
		@throw [OFInvalidArgumentException exception];

	if ((IRIHandler = [OFIRIHandler handlerForIRI: IRI]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithIRI: IRI];

	[IRIHandler setExtendedAttributeData: data
				     forName: name
	return [IRIHandler extendedAttributeForName: name ofItemAtIRI: IRI];
				 ofItemAtIRI: IRI];
}

#ifdef OF_FILE_MANAGER_SUPPORTS_EXTENDED_ATTRIBUTES
- (void)setExtendedAttributeData: (OFData *)data
- (OFData *)extendedAttributeForName: (OFString *)name
			ofItemAtPath: (OFString *)path
			 forName: (OFString *)name
		    ofItemAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFData *ret;

	ret = [self extendedAttributeForName: name
				 ofItemAtIRI: [OFIRI fileIRIWithPath: path]];
	[self setExtendedAttributeData: data
			       forName: name
			   ofItemAtIRI: [OFIRI fileIRIWithPath: path]];
	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
#endif
@end

@implementation OFDefaultFileManager
- (instancetype)autorelease
{

Modified src/OFIRIHandler.h from [a1527ceca1] to [326ecbc167].

146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+







 * @param attributes The attributes to set for the specified IRI
 * @param IRI The IRI of the item to set the attributes for
 * @@throw OFSetItemAttributesFailedException Failed to set the attributes of
 *					      the item
 * @throw OFUnsupportedProtocolException The handler cannot handle the IRI's
 *					 scheme
 * @throw OFNotImplementedException Setting one or more of the specified
 *				    attributes is not implpemented for the
 *				    attributes is not implemented for the
 *				    specified item
 */
- (void)setAttributes: (OFFileAttributes)attributes ofItemAtIRI: (OFIRI *)IRI;

/**
 * @brief Checks whether a file exists at the specified IRI.
 *
299
300
301
302
303
304
305


306
307
308






















309
310
311
299
300
301
302
303
304
305
306
307
308


309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333







+
+

-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * This method is not available for all IRIs.
 *
 * @param name The name of the extended attribute
 * @param IRI The IRI of the item to return the extended attribute from
 * @throw OFGetItemAttributesFailedException Getting the extended attribute
 *					     failed
 * @throw OFNotImplementedException Getting extended attributes is not
 *				    implemented for the specified item
 */
- (OFData *)extendedAttributeForName: (OFString *)name
			 ofItemAtIRI: (OFIRI *)IRI;
- (OFData *)extendedAttributeDataForName: (OFString *)name
			     ofItemAtIRI: (OFIRI *)IRI;

/**
 * @brief Sets the extended attribute data for the specified name for the
 *	  specified IRI.
 *
 * This method is not available for all IRIS.
 *
 * @param data The data for the extended attribute
 * @param name The name of the extended attribute
 * @param IRI The IRI of the item to set the extended attribute on
 * @throw OFSetItemAttributesFailedException Setting the extended attribute
 *					     failed
 * @throw OFUnsupportedProtocolException No handler is registered for the IRI's
 *					 scheme
 * @throw OFNotImplementedException Setting extended attributes is not
 *				    implemented for the specified item
 */
- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI;
@end

OF_ASSUME_NONNULL_END

Modified src/OFIRIHandler.m from [1620a3cb28] to [eaf120f6b8].

210
211
212
213
214
215
216

217

218


219






220
221
210
211
212
213
214
215
216
217

218
219
220
221

222
223
224
225
226
227
228
229







+
-
+

+
+
-
+
+
+
+
+
+


}

- (bool)moveItemAtIRI: (OFIRI *)source toIRI: (OFIRI *)destination
{
	return false;
}

- (OFData *)extendedAttributeDataForName: (OFString *)name
- (OFData *)extendedAttributeForName: (OFString *)name ofItemAtIRI: (OFIRI *)IRI
			     ofItemAtIRI: (OFIRI *)IRI
{
	OF_UNRECOGNIZED_SELECTOR
}
	return nil;

- (void)setExtendedAttributeData: (OFData *)data
			 forName: (OFString *)name
		     ofItemAtIRI: (OFIRI *)IRI
{
	OF_UNRECOGNIZED_SELECTOR
}
@end