1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 #include <sipwitch-config.h>
18 #include <ucommon/ucommon.h>
19 #include <ucommon/export.h>
22 #include <new>
23
24 #define USER_KEY_SIZE 177
25
27
28 static mempager cache_heap(16384);
30 static condlock_t user_lock;
32
35 {
37 }
38
41 {
42 }
43
45 {
49 time_t now;
50
51 time(&now);
52
53 while(node) {
54 after = (
Cache *)node->Next;
56 if(!prior)
57 *root = after;
58 else
59 prior->Next = after;
60 node->enlist(freelist);
61 }
62 else
63 prior = node;
64 node = after;
65 }
66 }
67
69 {
70 memset(&user_keys, 0, sizeof(user_keys));
71 }
72
74 {
76 user_lock.modify();
77 expire(&user_keys[i], &user_freelist);
78 user_lock.commit();
79 }
80 }
81
83 {
85 char buffer[128];
86 time_t now;
87
88 if(!fp) {
89 shell::log(shell::ERR, "%s\n",
90 _TEXT("usercache; cannot access file"));
91 return;
92 }
93
95 user_lock.access();
96 time(&now);
97 linked_pointer<UserCache> up = user_keys[i];
98 while(is(up)) {
99 if(!up->expires || up->expires > now) {
100 Socket::query((struct sockaddr *)(&up->address), buffer, sizeof(buffer));
101 if(up->expires)
102 fprintf(fp, "%s=%s; expires=%ld\n",
103 up->userid, buffer, (long)(up->expires - now));
104 else
105 fprintf(fp, "%s=%s\n", up->userid, buffer);
106 }
107 up.next();
108 }
109 user_lock.release();
110 }
111
112 fclose(fp);
113 }
114
116 {
117 assert(id != NULL && *id != 0);
118
119 linked_pointer<UserCache> up;
121 up = user_keys[path];
122 while(up) {
123 if(eq(up->userid, id))
124 break;
125 up.next();
126 }
127 return *up;
128 }
129
131 {
132 time_t now;
133 time(&now);
134
135 if(strchr(id, '@'))
136 return NULL;
137
138 user_lock.access();
140 if(cp) {
142 return cp;
143 }
144 user_lock.release();
145 return NULL;
146 }
147
149 {
150 LinkedObject::release();
151 }
152
154 {
155 if(entry)
156 user_lock.release();
157 }
158
159 void UserCache::add(
const char *
id,
struct sockaddr *addr, time_t create,
unsigned expire)
160 {
161 assert(id != NULL && *id != 0);
162
163 if(strchr(id, '@'))
164 return;
165
167
168 user_lock.modify();
170 if(cp) {
171 // only update if not trumped by existing entry...
173 goto update;
175 }
176
177 if(user_freelist) {
179 user_freelist = cp->Next;
180 }
181 else {
182 void *mp = cache_heap.alloc(
sizeof(
UserCache));
184 }
185
186 cp->enlist(&user_keys[path]);
188
189 update:
191 if(expire) {
194 }
195 else
198
200 user_lock.commit();
201 }
202
203 } // end namespace
static UserCache * request(const char *id)
static void userdump(void)
static void expire(LinkedObject **list, LinkedObject **free)
static void cleanup(void)
static UserCache * find(const char *id)
Find user record.
URI cache for tags, local, and remote id's.
static bool static FILE * output(const char *id)
Used to open an output session for returning control data.
Manage control interface.
static void add(const char *id, struct sockaddr *addr, time_t create, unsigned expire=130)
Add or refresh user in cache.
User caches may be used to contact nearby users in multicast registries.
void set(struct sockaddr *addr)