1 /*********************************************************************************************************
2 * Software License Agreement (BSD License) *
3 * Author: Sebastien Decugis <sdecugis@freediameter.net> *
4 * *
5 * Copyright (c) 2011, WIDE Project and NICT *
6 * All rights reserved. *
7 * *
8 * Redistribution and use of this software in source and binary forms, with or without modification, are *
9 * permitted provided that the following conditions are met: *
10 * *
11 * * Redistributions of source code must retain the above *
12 * copyright notice, this list of conditions and the *
13 * following disclaimer. *
14 * *
15 * * Redistributions in binary form must reproduce the above *
16 * copyright notice, this list of conditions and the *
17 * following disclaimer in the documentation and/or other *
18 * materials provided with the distribution. *
19 * *
20 * * Neither the name of the WIDE Project or NICT nor the *
21 * names of its contributors may be used to endorse or *
22 * promote products derived from this software without *
23 * specific prior written permission of WIDE Project and *
24 * NICT. *
25 * *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34 *********************************************************************************************************/
35
36 #include "fdcore-internal.h"
37
38 /* Merge information into a list of apps */
fd_app_merge(struct fd_list * list,application_id_t aid,vendor_id_t vid,int auth,int acct)39 int fd_app_merge(struct fd_list * list, application_id_t aid, vendor_id_t vid, int auth, int acct)
40 {
41 struct fd_list * li;
42 int skip = 0;
43
44 /* List is ordered by appid. Avoid duplicates */
45 for (li = list; li->next != list; li = li->next) {
46 struct fd_app * na = (struct fd_app *)(li->next);
47 if (na->appid < aid)
48 continue;
49
50 if (na->appid > aid)
51 break;
52
53 /* Otherwise, we merge with existing entry -- ignore vendor id in this case */
54 skip = 1;
55
56 if (auth)
57 na->flags.auth = 1;
58 if (acct)
59 na->flags.acct = 1;
60 break;
61 }
62
63 if (!skip) {
64 struct fd_app * new = NULL;
65
66 CHECK_MALLOC( new = malloc(sizeof(struct fd_app)) );
67 memset(new, 0, sizeof(struct fd_app));
68 fd_list_init(&new->chain, NULL);
69 new->flags.auth = (auth ? 1 : 0);
70 new->flags.acct = (acct ? 1 : 0);
71 new->vndid = vid;
72 new->appid = aid;
73 fd_list_insert_after(li, &new->chain);
74 }
75
76 return 0;
77 }
78
79 /* Check if a given application id is in a list */
fd_app_check(struct fd_list * list,application_id_t aid,struct fd_app ** detail)80 int fd_app_check(struct fd_list * list, application_id_t aid, struct fd_app **detail)
81 {
82 struct fd_list * li;
83
84 TRACE_ENTRY("%p %d %p", list, aid, detail);
85 CHECK_PARAMS(list && detail);
86
87 *detail = NULL;
88
89 /* Search in the list */
90 for (li = list->next; li != list; li = li->next) {
91 struct fd_app * a = (struct fd_app *)li;
92 if (a->appid < aid)
93 continue;
94
95 if (a->appid == aid)
96 *detail = a;
97 break;
98 }
99
100 return 0;
101 }
102
103 /* Check if two lists have at least one common application */
fd_app_check_common(struct fd_list * list1,struct fd_list * list2,int * common_found)104 int fd_app_check_common(struct fd_list * list1, struct fd_list * list2, int * common_found)
105 {
106 struct fd_list * li1, *li2;
107
108 TRACE_ENTRY("%p %p %p", list1, list2, common_found);
109 CHECK_PARAMS( list1 && list2 && common_found );
110
111 /* Both lists are ordered, so advance both pointers at the same time */
112 for (li1 = list1->next, li2 = list2->next; (li1 != list1) && (li2 != list2); ) {
113 struct fd_app * a1 = (struct fd_app *)li1, *a2 = (struct fd_app *)li2;
114 if (a1->appid < a2->appid) {
115 li1 = li1->next;
116 continue;
117 }
118 if (a1->appid > a2->appid) {
119 li2 = li2->next;
120 continue;
121 }
122 /* They are equal, compare the applications */
123 if ((a1->flags.auth && a2->flags.auth) || (a1->flags.acct && a2->flags.acct)) {
124 /* found! */
125 *common_found = 1;
126 return 0;
127 }
128
129 /* This application is not common, advance both lists */
130 li1 = li1->next;
131 li2 = li2->next;
132 }
133
134 /* We did not find a common app */
135 *common_found = 0;
136 return 0;
137 }
138
139 /* Remove the apps from a list */
fd_app_empty(struct fd_list * list)140 int fd_app_empty(struct fd_list * list)
141 {
142 TRACE_ENTRY("%p", list);
143 CHECK_PARAMS( list );
144
145 while (!FD_IS_LIST_EMPTY(list)) {
146 struct fd_list * li = list->next;
147 fd_list_unlink(li);
148 free(li);
149 }
150
151 return 0;
152 }
153