Revert "init: Assign set value to avoid ambiguity"
[platform/core/system/tizen-platform-wrapper.git] / src / shared-api.c
1 /*
2  * Copyright (C) 2013-2014 Intel Corporation.
3  * 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors:
19  *   José Bollo <jose.bollo@open.eurogiciel.org>
20  *   Stéphane Desneux <stephane.desneux@open.eurogiciel.org>
21  *   Jean-Benoit Martin <jean-benoit.martin@open.eurogiciel.org>
22  *
23  */
24 #define _GNU_SOURCE
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <assert.h>
34 #include <syslog.h>
35
36 #ifndef NOT_MULTI_THREAD_SAFE
37 #include <pthread.h>
38 #endif
39
40 #include "tzplatform_variables.h"
41 #include "tzplatform_config.h"
42 #include "heap.h"
43 #include "scratch.h"
44 #include "passwd.h"
45 #include "foreign.h"
46 #include "context.h"
47 #include "hashing.h"
48 #include "init.h"
49 #include "shared-api.h"
50
51
52 /* the global context */
53 static struct tzplatform_context global_context = {
54 #ifndef NOT_MULTI_THREAD_SAFE
55     .mutex = PTHREAD_MUTEX_INITIALIZER,
56 #endif
57     .state = RESET,
58     .user = _USER_NOT_SET_
59 };
60
61 /* the signup of names */
62 #include "signup.inc"
63
64 /* validate the signup */
65 static void validate_signup(char signup[33])
66 {
67     if (memcmp(signup+1, tizen_platform_config_signup+1, 32)) {
68         syslog(LOG_CRIT, "Bad signup of the client of tizen-platform-config");
69         abort();
70     }
71     signup[0] = 1;
72 }
73
74 /* check the signup */
75 static inline void check_signup(char signup[33])
76 {
77     if (!signup[0])
78         validate_signup(signup);
79 }
80
81 /* locks the context */
82 inline static void lock(struct tzplatform_context *context)
83 {
84 #ifndef NOT_MULTI_THREAD_SAFE
85     pthread_mutex_lock( &context->mutex);
86 #endif
87 }
88
89 /* unlock the context */
90 inline static void unlock(struct tzplatform_context *context)
91 {
92 #ifndef NOT_MULTI_THREAD_SAFE
93     pthread_mutex_unlock( &context->mutex);
94 #endif
95 }
96
97 static inline const char *get_lock(int id, struct tzplatform_context *context)
98 {
99     lock( context);
100
101     if (id < 0 || (int)_TZPLATFORM_VARIABLES_COUNT_ <= id)
102         return NULL;
103
104     if (context->state == RESET)
105         initialize( context);
106
107     return context->state == ERROR ? NULL : context->values[id];
108 }
109
110 /*************** PUBLIC API begins here **************/
111
112 int tzplatform_context_create(struct tzplatform_context **result)
113 {
114     struct tzplatform_context *context;
115
116     context = malloc( sizeof * context);
117     *result = context;
118     if (context == NULL)
119         return -1;
120
121     context->state = RESET;
122     context->user = _USER_NOT_SET_;
123 #ifndef NOT_MULTI_THREAD_SAFE
124     pthread_mutex_init( &context->mutex, NULL);
125 #endif
126     return 0;
127 }
128
129 void tzplatform_context_destroy(struct tzplatform_context *context)
130 {
131     if (context->state == VALID)
132             heap_destroy( &context->heap);
133     context->state = ERROR;
134     free( context);
135 }
136
137 void tzplatform_reset()
138 {
139     tzplatform_context_reset(&global_context);
140 }
141
142 void tzplatform_context_reset(struct tzplatform_context *context)
143 {
144     lock( context);
145     if (context->state != RESET) {
146         if (context->state == VALID)
147             heap_destroy( &context->heap);
148         context->state = RESET;
149     }
150     unlock( context);
151 }
152
153 uid_t tzplatform_get_user(char signup[33])
154 {
155     return tzplatform_context_get_user( &global_context);
156 }
157
158 uid_t tzplatform_context_get_user(struct tzplatform_context *context)
159 {
160     uid_t result;
161
162     lock( context);
163     result = get_uid( context);
164     unlock( context);
165
166     return result;
167 }
168
169 void tzplatform_reset_user()
170 {
171     tzplatform_context_reset_user( &global_context);
172 }
173
174 void tzplatform_context_reset_user(struct tzplatform_context *context)
175 {
176     tzplatform_context_set_user( context, _USER_NOT_SET_);
177 }
178
179 int tzplatform_set_user(uid_t uid)
180 {
181     return tzplatform_context_set_user( &global_context, uid);
182 }
183
184 int tzplatform_context_set_user(struct tzplatform_context *context, uid_t uid)
185 {
186     lock( context);
187     if (context->user != uid) {
188         if (uid != _USER_NOT_SET_ && !pw_has_uid( uid)) {
189             unlock( context);
190             return -1;
191         }
192         else {
193             if (context->state == VALID)
194                 heap_destroy( &context->heap);
195             context->state = RESET;
196             context->user = uid;
197         }
198     }
199     unlock( context);
200
201     return 0;
202 }
203
204 /*************** PUBLIC INTERNAL API begins here **************/
205
206 const char* _getname_tzplatform_(int id, char signup[33])
207 {
208     check_signup(signup);
209     return 0 <= id && id < _TZPLATFORM_VARIABLES_COUNT_ ? keyname(id) : NULL;
210 }
211
212 int _getid_tzplatform_(const char *name, char signup[33])
213 {
214     check_signup(signup);
215     return hashid(name, strlen(name));
216 }
217
218 const char* _getenv_tzplatform_(int id, char signup[33]) 
219 {
220     return _context_getenv_tzplatform_(id, signup, &global_context);
221 }
222
223 const char* _context_getenv_tzplatform_(int id, char signup[33], struct tzplatform_context *context)
224 {
225     const char *array[2];
226     const char *result;
227
228     check_signup(signup);
229     result = get_lock(id, context);
230     if (result != NULL) {
231         array[0] = result;
232         array[1] = NULL;
233         result = scratchcat( 0, array);
234     }
235     unlock( context);
236     return result;
237 }
238
239 int _getenv_int_tzplatform_(int id, char signup[33])
240 {
241     return _context_getenv_int_tzplatform_(id, signup, &global_context);
242 }
243
244 int _context_getenv_int_tzplatform_(int id, char signup[33], struct tzplatform_context *context)
245 {
246     const char *value;
247     int result;
248
249     check_signup(signup);
250     value = get_lock(id, context);
251     result = value==NULL ? -1 : atoi(value);
252     unlock( context);
253     return result;
254 }
255
256 const char* _mkstr_tzplatform_(int id, const char * str, char signup[33])
257 {
258     return _context_mkstr_tzplatform_(id, str, signup,  &global_context);
259 }
260
261 const char* _context_mkstr_tzplatform_(int id, const char *str, char signup[33], struct tzplatform_context *context)
262 {
263     const char *array[3];
264     const char *result;
265
266     check_signup(signup);
267     result = get_lock(id, context);
268     if (result != NULL) {
269         array[0] = result;
270         array[1] = str;
271         array[2] = NULL;
272         result = scratchcat( 0, array);
273     }
274     unlock( context);
275     return result;
276 }
277
278 const char* _mkpath_tzplatform_(int id, const char * path, char signup[33])
279 {
280     return _context_mkpath_tzplatform_(id, path, signup,  &global_context);
281 }
282
283 const char* _context_mkpath_tzplatform_(int id, const char *path, char signup[33], struct tzplatform_context *context)
284 {
285     const char *array[3];
286     const char *result;
287
288     check_signup(signup);
289     result = get_lock(id, context);
290     if (result != NULL) {
291         array[0] = result;
292         array[1] = path;
293         array[2] = NULL;
294         result = scratchcat( 1, array);
295     }
296     unlock( context);
297     return result;
298 }
299
300 const char* _mkpath3_tzplatform_(int id, const char * path, const char* path2, char signup[33])
301 {
302     return _context_mkpath3_tzplatform_( id, path, path2, signup,  &global_context);
303 }
304
305 const char* _context_mkpath3_tzplatform_(int id, const char *path, const char *path2, char signup[33], struct tzplatform_context *context)
306 {
307     const char *array[4];
308     const char *result;
309
310     check_signup(signup);
311     result = get_lock(id, context);
312     if (result != NULL) {
313         array[0] = result;
314         array[1] = path;
315         array[2] = path2;
316         array[3] = NULL;
317         result = scratchcat( 1, array);
318     }
319     unlock( context);
320     return result;
321 }
322
323 const char* _mkpath4_tzplatform_(int id, const char * path, const char* path2, const char *path3, char signup[33])
324 {
325     return _context_mkpath4_tzplatform_( id, path, path2, path3, signup,  &global_context);
326 }
327
328 const char* _context_mkpath4_tzplatform_(int id, const char *path, const char *path2, const char *path3, char signup[33], struct tzplatform_context *context)
329 {
330     const char *array[5];
331     const char *result;
332
333     check_signup(signup);
334     result = get_lock(id, context);
335     if (result != NULL) {
336         array[0] = result;
337         array[1] = path;
338         array[2] = path2;
339         array[3] = path3;
340         array[4] = NULL;
341         result = scratchcat( 1, array);
342     }
343     unlock( context);
344     return result;
345 }
346
347 uid_t _getuid_tzplatform_(int id, char signup[33])
348 {
349     return _context_getuid_tzplatform_( id, signup,  &global_context);
350 }
351
352 uid_t _context_getuid_tzplatform_(int id, char signup[33], struct tzplatform_context *context)
353 {
354     uid_t result;
355     const char *value;
356
357     check_signup(signup);
358     result = (uid_t)-1;
359     value = get_lock(id, context);
360     if (value != NULL) {
361         pw_get_uid( value, &result);
362     }
363     unlock( context);
364     return result;
365 }
366
367 gid_t _getgid_tzplatform_(int id, char signup[33])
368 {
369     return _context_getgid_tzplatform_( id, signup,  &global_context);
370 }
371
372 gid_t _context_getgid_tzplatform_(int id, char signup[33], struct tzplatform_context *context)
373 {
374     gid_t result;
375     const char *value;
376
377     check_signup(signup);
378     result = (uid_t)-1;
379     value = get_lock(id, context);
380     if (value != NULL) {
381         pw_get_gid( value, &result);
382     }
383     unlock( context);
384     return result;
385 }
386