1 .\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 .\" The contents of this file constitute Original Code as defined in and
4 .\" are subject to the Apple Public Source License Version 1.1 (the
5 .\" "License"). You may not use this file except in compliance with the
6 .\" License. Please obtain a copy of the License at
7 .\" http://www.apple.com/publicsource and read it before using this file.
9 .\" This Original Code and all software distributed under the License are
10 .\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
11 .\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
12 .\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
13 .\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
14 .\" License for the specific language governing rights and limitations
15 .\" under the License.
24 .Nd search a volume quickly
26 .Fd #include <sys/attr.h>
27 .Fd #include <unistd.h>
29 .Fn searchfs "const char * path" "struct fssearchblock * searchBlock" "unsigned long * numMatches" "unsigned long scriptCode" "unsigned long options" "struct searchstate * state"
34 function searches the volume (that is, mounted file system) specified by
36 for file system objects matching the criteria specified by
43 parameter returns the number of matching file system objects found.
44 The function also returns attributes of those file system objects in a buffer
49 parameter allows you search the volume using multiple calls to
51 resuming the search where it left off.
52 The routine will only return objects to which you have access (that is, you
53 have execute permissions on the directories leading to this object from the root).
60 parameter must reference a valid file system object on the volume to be searched.
61 Typically the path is to the volume's root directory.
62 The entire volume is always searched.
63 All directories listed in the path name leading to this object must be
67 .\" searchBlock parameter
71 parameter is a pointer to an
73 structure, as defined by
76 You are responsible for filling out all fields of this structure before calling the function.
78 struct fssearchblock {
79 struct attrlist * returnattrs;
81 size_t returnbuffersize;
82 unsigned long maxmatches;
83 struct timeval timelimit;
85 size_t sizeofsearchparams1;
87 size_t sizeofsearchparams2;
88 struct attrlist searchattrs;
93 For information about the
95 structure, see the discussion of
99 .\" searchBlock elements
103 structure are defined as follows.
104 .Bl -tag -width sizeofsearchparams1
108 can return arbitrary attributes of the file system objects that it finds.
109 This field must point to an
111 structure that specifies the attributes that you want returned.
112 To request an attribute you must set the corresponding bit in the appropriate
117 You are responsible for filling out all fields of this structure before calling the function.
118 You must not request volume attributes.
122 places attributes of the matching file system objects into this returned attributes buffer.
123 The attributes for any given object are grouped together and
124 packed in exactly the same way as they would be returned from
125 .Xr getdirentriesattr 2 .
126 The initial contents of this buffer are ignored.
129 Set this field to the size, in bytes, of the buffer pointed to by
133 Specifies the maximum number of matches that you want this call to
138 Specifies the maximum time that you want this call to
143 If you're implementing a volume format, you should impose your own internal
144 limit on the duration of this call to prevent a malicious user program
145 from monopolising kernel resources.
149 Specifies the lower bound of the search criteria.
150 This is discussed in detail below.
151 You must place attribute values into the buffer in the same
152 way as they would be returned by
156 field determines the exact layout of the attribute values.
158 .It sizeofsearchparams1
159 Set this field to the size, in bytes, of the buffer pointed to by
163 Specifies the upper bound of the search criteria.
164 This is discussed in detail below.
165 You must place attribute values into the buffer in the same
166 way as they would be returned by
170 field determines the exact layout of the attribute values.
172 .It sizeofsearchparams2
173 Set this field to the size, in bytes, of the buffer pointed to by
177 Specifies the attributes that you want you use for your search criteria.
178 You are responsible for filling out all fields of this structure before calling the function.
179 To search for an attribute you must set the corresponding bit in the appropriate
183 structure, and place the appropriate values into the
188 The attributes specified here determine the format of those buffers.
189 This is discussed in detail below.
194 .\" numMatches parameter
198 parameter points to an
201 The initial value of this variable is ignored.
202 On return, this variable contains the number of matching file system objects found.
203 The is always less than or equal to the
208 The attributes for the matching objects have been placed into the returned attributes buffer.
211 .\" scriptCode parameter
215 parameter is currently ignored.
216 You should always pass in the value 0x08000103, which corresponds to the
217 UTF-8 text encoding value defined by
218 .Aq Pa CarbonCore/TextCommon.h .
221 .\" options parameter
225 parameter is a bit set that controls the behaviour of
227 The following option bits are defined.
229 .Bl -tag -width SRCHFS_MATCHPARTIALNAMES
236 parameter and start a new search.
241 is valid and attempts to resume a previous search based on that state.
243 .It SRCHFS_MATCHPARTIALNAMES
246 will consider substrings to be successful matches when evaluating the
253 will search for directories that match the search criteria.
254 To get meaningful results you must specify either this bit or
255 .Dv SRCHFS_MATCHFILES ,
258 .It SRCHFS_MATCHFILES
261 will search for files that match the search criteria.
262 To get meaningful results you must specify either this bit or
263 .Dv SRCHFS_MATCHDIRS ,
269 will only return one reference for a hard linked file, rather that a reference
270 for each hard link to the file.
272 This option is not recommended for general development.
273 Its primary client is the
278 This option is privileged (the caller's effective UID must be 0) and cannot
279 be used if you request the
282 .Dv ATTR_CMN_PAROBJID
285 Introduced with Darwin 7.0 (Mac OS X version 10.3).
287 .It SRCHFS_SKIPINVISIBLE
290 will not match any invisible file system objects (that is, objects whose
291 .Dv ATTR_CMN_FNDRINFO
292 attribute has bit 6 set in the ninth byte) or any objects within
293 invisible directories.
295 Introduced with Darwin 7.0 (Mac OS X version 10.3).
297 .It SRCHFS_SKIPPACKAGES
300 will not match any file system objects that are inside a package.
301 A package is defined as a directory whose extension matches one
302 of the extensions that are configured into the kernel by Launch Services.
304 Introduced with Darwin 7.0 (Mac OS X version 10.3).
306 .It SRCHFS_SKIPINAPPROPRIATE
309 will not match any file system objects that are within an inappropriate directory.
310 The current list of inappropriate directories contains one item: /System.
312 Introduced with Darwin 7.0 (Mac OS X version 10.3).
314 .It SRCHFS_NEGATEPARAMS
317 will return all the file system objects that do not match the search criteria.
319 Introduced with Darwin 7.0 (Mac OS X version 10.3).
328 parameter is a pointer to an opaque data structure that
330 uses to maintain the state of a search between successive calls.
331 In your first call to
340 that the search state is invalid and that it should start a new search.
341 When this call completes, it may have only returned partial results;
342 in that case, it will have updated the structure pointed to by
346 again, this time without specifying the
350 parameter, it will resume the search where it left off, using the search state
351 that it previously stored in the state structure.
352 You do not need to explicitly dispose of this state.
357 function returns significant errors in the followings cases.
362 If it has found as many objects as you requested in the
366 parameter, it will return
370 If there is not enough space in the returned attributes buffer for the first match,
373 You should allocate a larger returned attributes buffer and try again.
375 will be zero in this case.
378 If the timeout expires it will return
382 If you attempt to resume a search (that is,
384 is not specified in the
386 parameter) and the catalog has changed since the last search,
387 the function will return
389 You must start your search again from the beginning.
400 may be greater than zero.
401 This is known as a partial result.
402 You should be sure to process these matches before calling
408 You specify the search criteria using a combination of the
411 .Fa sizeofsearchparams1,
414 .Fa sizeofsearchparams2
417 parameter, and various flags in the
422 field determines the attributes considered when comparing a file system object to
424 You can specify that an attribute should be considered by setting the corresponding
425 bit in the appropriate
430 See the discussion of
432 for a detailed description of this structure.
437 .Fa sizeofsearchparams1 ,
440 .Fa sizeofsearchparams2
441 fields specify the attribute values that must be matched.
442 The format of each of these buffers is determined by the attributes that you're searching for.
443 The values are packed in exactly the same way as they would be returned from
445 including the leading
450 The attribute values in the first and second search buffers form a lower and upper bound for
451 the search, respectively.
452 These have different meanings depending on the type of attribute.
457 For string attributes (specifically
459 the object name), the value in the first search
460 buffer is significant and the value in the second search buffer is ignored.
461 The string comparison is either an exact match or a substring match depending on
463 .Dv SRCHFS_MATCHPARTIALNAMES
469 For structured attributes (specifically
470 .Dv ATTR_CMN_FNDRINFO ,
471 the Finder information), the value from the
472 file system object is masked (logical AND) with the value in the second search buffer and then
473 compared, byte for byte, against the value in the first search buffer.
474 If it is equal, the object is a match.
477 For scalar attributes (all other attributes, for example,
478 .Dv ATTR_CMN_MODTIME ,
479 the modification date), the values in the first and second search
480 buffers are literally a lower and upper bound.
481 An object matches the criteria if its value is greater than or equal to the value in
482 the first buffer and less than or equal to the value in the second.
487 Upon successful completion, a value of 0 is returned.
488 This means that the entire volume has been searched and all matches returned.
489 Otherwise, a value of -1 is returned and
491 is set to indicate the error.
494 See the discussion of the
502 Not all volumes support
504 You can test whether a volume supports
508 to get the volume capabilities attribute
509 .Dv ATTR_VOL_CAPABILITIES ,
511 .Dv VOL_CAP_INT_SEARCHFS
517 function has been undocumented for more than two years.
518 In that time a number of volume format implementations have been created without
519 a proper specification for the behaviour of this routine.
520 You may encounter volume format implementations with slightly different
521 behaviour than what is described here.
522 Your program is expected to be tolerant of this variant behaviour.
525 If you're implementing a volume format that supports
527 you should be careful to support the behaviour specified by this document.
530 A bug in systems prior to Darwin 7.0 (Mac OS X version 10.3) makes searching for the
531 .Dv ATTR_CMN_BKUPTIME
533 The bug causes the attribute to consume two items in the search attribute buffers, the
534 first in the proper place and the second between
535 .Dv ATTR_CMN_FNDRINFO
537 .Dv ATTR_CMN_OWNERID .
545 The volume does not support
549 A component of the path prefix is not a directory.
551 .It Bq Er ENAMETOOLONG
552 A component of a path name exceeded
554 characters, or an entire path name exceeded
559 The file system object does not exist.
562 Search permission is denied for a component of the path prefix.
565 Too many symbolic links were encountered in translating the pathname.
568 One of the pointer parameters points to an invalid address.
573 parameter contains an invalid flag or sizeofsearchparams1/2 is greater than
574 SEARCHFS_MAX_SEARCHPARMS (see attr.h).
577 The search terminated with partial results, either because
579 has hit the limit specified by
581 or because the timeout expired.
582 Process the matches returned so far and then call
584 again to look for more.
588 The returned attributes buffer is too small for the first match.
589 You should allocate a larger returned attributes buffer and try again.
591 will be zero in this case.
594 The search could not be resumed because the volume has changed.
597 An I/O error occurred while reading from or writing to the file system.
602 Not all attributes can be searched for using
604 The list currently includes:
643 ATTR_FILE_DATAALLOCSIZE
647 ATTR_FILE_RSRCALLOCSIZE
652 The following code searches a volume for files of the specified type and creator.
659 #include <sys/attr.h>
660 #include <sys/errno.h>
664 typedef struct attrlist attrlist_t;
665 typedef struct fssearchblock fssearchblock_t;
666 typedef struct searchstate searchstate_t;
669 struct SearchAttrBuf {
670 unsigned long length;
673 typedef struct SearchAttrBuf SearchAttrBuf;
676 struct ResultAttrBuf {
677 unsigned long length;
678 attrreference_t name;
681 typedef struct ResultAttrBuf ResultAttrBuf;
689 static int SearchFSDemo(
696 fssearchblock_t searchBlock;
699 static const unsigned char kAllOnes[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
700 unsigned long matchCount;
701 unsigned long matchIndex;
702 unsigned long options;
704 ResultAttrBuf * thisEntry;
705 attrlist_t returnAttrList;
706 char resultAttrBuf[ kMatchesPerCall
707 * (sizeof(ResultAttrBuf) + 64)];
710 // resultAttrBuf is big enough for kMatchesPerCall entries,
711 // assuming that the average name length is less than 64.
714 assert(strlen(type) == 4);
715 assert(strlen(creator) == 4);
718 memset(&searchBlock, 0, sizeof(searchBlock));
719 searchBlock.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT;
720 searchBlock.searchattrs.commonattr = ATTR_CMN_FNDRINFO;
723 memset(&lower, 0, sizeof(lower));
724 memset(&upper, 0, sizeof(upper));
725 lower.length = sizeof(lower);
726 upper.length = sizeof(upper);
727 memcpy(&lower.finderInfo[0], type, 4);
728 memcpy(&lower.finderInfo[4], creator, 4);
729 memcpy(&upper.finderInfo[0], kAllOnes, 4);
730 memcpy(&upper.finderInfo[4], kAllOnes, 4);
731 searchBlock.searchparams1 = &lower;
732 searchBlock.sizeofsearchparams1 = sizeof(lower);
733 searchBlock.searchparams2 = &upper;
734 searchBlock.sizeofsearchparams2 = sizeof(lower);
737 searchBlock.timelimit.tv_sec = 0;
738 searchBlock.timelimit.tv_usec = 100 * 1000;
741 searchBlock.maxmatches = kMatchesPerCall;
744 memset(&returnAttrList, 0, sizeof(returnAttrList));
745 returnAttrList.bitmapcount = ATTR_BIT_MAP_COUNT;
746 returnAttrList.commonattr = ATTR_CMN_NAME | ATTR_CMN_PAROBJID;
749 searchBlock.returnattrs = &returnAttrList;
750 searchBlock.returnbuffer = resultAttrBuf;
751 searchBlock.returnbuffersize = sizeof(resultAttrBuf);
754 options = SRCHFS_START | SRCHFS_MATCHFILES;
769 if ( (err == 0) || (err == EAGAIN) ) {
770 thisEntry = (ResultAttrBuf *) resultAttrBuf;
773 for (matchIndex = 0; matchIndex < matchCount; matchIndex++) {
774 printf("%08x ", thisEntry->parObjID.fid_objno);
777 ((char *) &thisEntry->name)
778 + thisEntry->name.attr_dataoffset
781 // Advance to the next entry.
783 ((char *) thisEntry) += thisEntry->length;
788 options &= ~SRCHFS_START;
789 } while (err == EAGAIN);
803 function call appeared in Darwin 1.3.1 (Mac OS X version 10.0).