1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 ss_attr_t *
 ss_attr_find(ss_pers_t *owner,                  /* The object for which we're searching for attributes. */
              const char *name,                  /* An optional attribute name on which to restrict the search. */
              size_t nskip,                      /* Skip the first SKIP matching attributes. */
              size_t maxret,                     /* Return at most MAXRET matching attributes. If the caller passes SS_NOSIZE
                                                  * then all matching attributes are returned. If more than MAXRET attributes
                                                  * could be returned the remainder are simply discarded.  If RESULT is
                                                  * non-null then this argument should reflect the size of that array. */
              size_t *nret,                      /* OUT: The number of attributes stored in the returned array of links. */
              ss_attr_t *result                  /* An optional buffer in which to store links to the matching attributes. If
                                                  * supplied, this will be the successful return value. The constant
                                                  * SS_PERS_TEST can be supplied in order to prevent the library from
                                                  * allocating a return value (this is useful if the caller simply wants to
                                                  * count the matches). */
              )
 {
     SS_ENTER(ss_attr_find, ss_attr_tP);
     static ss_attr_t    *key;                   /* Key of values to use when searching the attribute table */
     ss_attrobj_t        mask;                   /* What parts of KEY are significant and how? */
     ss_scope_t          scope=SS_SCOPE_NULL;    /* The scope containing OWNER */

     SS_ASSERT_CLASS(owner, ss_pers_t);
     if (!nret) SS_ERROR_FMT(USAGE, ("NRET argument was null"));
     if (NULL==ss_pers_scope(owner, &scope)) SS_ERROR(FAILED);

     /* Create or reset key and mask */
     memset(&mask, 0, sizeof mask);
     if (!key && NULL==(key=SS_PERS_NEW(sslib_g.temp.tscope, ss_attr_t, 0))) {
         SS_ERROR(FAILED);
     } else if (ss_pers_reset((ss_pers_t*)key, 0)<0) {
         SS_ERROR(FAILED);
     }

     /* Initialize key and mask with values for which to search */
     SS_ATTR(key)->owner = *owner;
     memset(&(mask.owner), SS_VAL_CMP_DFLT, 1);
     if (name) {
         ss_string_set(SS_ATTR_P(key,name), name);
         memset(&(mask.name), SS_VAL_CMP_DFLT, 1);
     }

     /* Search */
     *nret = maxret;
     if (NULL==(result=(ss_attr_t*)ss_pers_find(&scope, (ss_pers_t*)key, (ss_persobj_t*)&mask, nskip, nret,
                                                (ss_pers_t*)result, NULL))) {
         SS_ERROR(FAILED);
     }

 SS_CLEANUP:
     if (nret) *nret = 0;
     SS_LEAVE(result);
 }