]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/blob - libc/bionic/stubs.c
auto import from //depot/cupcake/@135843
[android-sdk/platform-bionic.git] / libc / bionic / stubs.c
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #include <grp.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <pwd.h>
32 #include <netdb.h>
33 #include <mntent.h>
34 #include <private/android_filesystem_config.h>
35 #include <pthread.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <ctype.h>
40 /** Thread-specific state for the stubs functions
41  **/
43 pthread_once_t   the_once = PTHREAD_ONCE_INIT;
44 pthread_key_t    the_key;
46 typedef struct {
47     struct passwd  passwd;
48     struct group   group;
49     char*          group_members[2];
50     char           app_name_buffer[32];
51     char           group_name_buffer[32];
52 } stubs_state_t;
54 static void
55 stubs_state_free( void*  _s )
56 {
57     stubs_state_t*  s = _s;
58     free(s);
59 }
61 static stubs_state_t*
62 stubs_state_alloc( void )
63 {
64     stubs_state_t*  s = calloc(1, sizeof *s);
66     if (s != NULL) {
67         s->group.gr_mem = s->group_members;
68     }
69     return s;
70 }
72 static void __stubs_key_init(void)
73 {
74     pthread_key_create( &the_key, stubs_state_free );
75 }
77 static stubs_state_t*
78 __stubs_state(void)
79 {
80     stubs_state_t*  s;
82     pthread_once(&the_once, __stubs_key_init);
83     s = pthread_getspecific(the_key);
84     if (s == NULL) {
85         s = stubs_state_alloc();
86         if (s == NULL) {
87             errno = ENOMEM;  /* just in case */
88         } else {
89             if ( pthread_setspecific(the_key, s) != 0 ) {
90                 stubs_state_free(s);
91                 errno = ENOMEM;
92                 s     = NULL;
93             }
94         }
95     }
96     return s;
97 }
99 static struct passwd*
100 android_iinfo_to_passwd( struct passwd          *pw,
101                          struct android_id_info *iinfo )
103     pw->pw_name  = (char*)iinfo->name;
104     pw->pw_uid   = iinfo->aid;
105     pw->pw_gid   = iinfo->aid;
106     pw->pw_dir   = "/";
107     pw->pw_shell = "/system/bin/sh";
108     return pw;
111 static struct group*
112 android_iinfo_to_group( struct group *gr,
113                         struct android_id_info *iinfo )
115     gr->gr_name   = (char*) iinfo->name;
116     gr->gr_gid    = iinfo->aid;
117     gr->gr_mem[0] = gr->gr_name;
118     gr->gr_mem[1] = NULL;
119     return gr;
122 static struct passwd *
123 android_id_to_passwd( struct passwd *pw, unsigned id)
125     struct android_id_info *iinfo = android_ids;
126     unsigned n;
127     for (n = 0; n < android_id_count; n++) {
128         if (iinfo[n].aid == id) {
129             return android_iinfo_to_passwd(pw, iinfo + n);
130         }
131     }
132     return NULL;
135 static struct passwd*
136 android_name_to_passwd(struct passwd *pw, const char *name)
138     struct android_id_info *iinfo = android_ids;
139     unsigned n;
140     for (n = 0; n < android_id_count; n++) {
141         if (!strcmp(iinfo[n].name, name)) {
142             return android_iinfo_to_passwd(pw, iinfo + n);
143         }
144     }
145     return NULL;
148 static struct group*
149 android_id_to_group( struct group *gr, unsigned id )
151     struct android_id_info *iinfo = android_ids;
152     unsigned n;
153     for (n = 0; n < android_id_count; n++) {
154         if (iinfo[n].aid == id) {
155             return android_iinfo_to_group(gr, iinfo + n);
156         }
157     }
158     return NULL;
161 static struct group*
162 android_name_to_group( struct group *gr, const char *name )
164     struct android_id_info *iinfo = android_ids;
165     unsigned n;
166     for (n = 0; n < android_id_count; n++) {
167         if (!strcmp(iinfo[n].name, name)) {
168             return android_iinfo_to_group(gr, iinfo + n);
169         }
170     }
171     return NULL;
174 /* translate a user/group name like app_1234 into the
175  * corresponding user/group id (AID_APP + 1234)
176  * returns 0 and sets errno to ENOENT in case of error
177  */
178 static unsigned
179 app_id_from_name( const char*  name )
181     unsigned long  id;
182     char*          end;
184     if (memcmp(name, "app_", 4) != 0 || !isdigit(name[4]))
185         goto FAIL;
187     id = strtoul(name+4, &end, 10);
188     if (id == 0 || *end != '\0')
189         goto FAIL;
191     id += AID_APP;
193     /* check for overflow and that the value can be
194      * stored in our 32-bit uid_t/gid_t */
195     if (id < AID_APP || (unsigned)id != id)
196         goto FAIL;
198     return (unsigned)id;
200 FAIL:
201     errno = ENOENT;
202     return 0;
205 /* translate a uid into the corresponding app_<uid>
206  * passwd structure (sets errno to ENOENT on failure)
207  */
208 static struct passwd*
209 app_id_to_passwd(uid_t  uid, stubs_state_t*  state)
211     struct passwd*  pw = &state->passwd;
213     if (uid < AID_APP) {
214         errno = ENOENT;
215         return NULL;
216     }
218     snprintf( state->app_name_buffer, sizeof state->app_name_buffer,
219               "app_%u", uid - AID_APP );
221     pw->pw_name  = state->app_name_buffer;
222     pw->pw_dir   = "/data";
223     pw->pw_shell = "/system/bin/sh";
224     pw->pw_uid   = uid;
225     pw->pw_gid   = uid;
227     return pw;
230 /* translate a gid into the corresponding app_<gid>
231  * group structure (sets errno to ENOENT on failure)
232  */
233 static struct group*
234 app_id_to_group(gid_t  gid, stubs_state_t*  state)
236     struct group*  gr = &state->group;
238     if (gid < AID_APP) {
239         errno = ENOENT;
240         return NULL;
241     }
243     snprintf(state->group_name_buffer, sizeof state->group_name_buffer,
244              "app_%u", gid - AID_APP);
246     gr->gr_name   = state->group_name_buffer;
247     gr->gr_gid    = gid;
248     gr->gr_mem[0] = gr->gr_name;
249     gr->gr_mem[1] = NULL;
251     return gr;
255 struct passwd*
256 getpwuid(uid_t uid)
258     stubs_state_t*  state = __stubs_state();
259     struct passwd*  pw;
261     if (state == NULL)
262         return NULL;
264     pw = &state->passwd;
266     if ( android_id_to_passwd(pw, uid) != NULL )
267         return pw;
269     return app_id_to_passwd(uid, state);
272 struct passwd*
273 getpwnam(const char *login)
275     stubs_state_t*  state = __stubs_state();
277     if (state == NULL)
278         return NULL;
280     if (android_name_to_passwd(&state->passwd, login) != NULL)
281         return &state->passwd;
283     return app_id_to_passwd( app_id_from_name(login), state );
286 int
287 getgrouplist (const char *user, gid_t group,
288               gid_t *groups, int *ngroups)
290     if (*ngroups < 1) {
291         *ngroups = 1;
292         return -1;
293     }
294     groups[0] = group;
295     return (*ngroups = 1);
298 char*
299 getlogin(void)
301     struct passwd *pw = getpwuid(getuid());
303     if(pw) {
304         return pw->pw_name;
305     } else {
306         return NULL;
307     }
310 struct group*
311 getgrgid(gid_t gid)
313     stubs_state_t*  state = __stubs_state();
314     struct group*   gr;
316     if (state == NULL)
317         return NULL;
319     gr = android_id_to_group(&state->group, gid);
320     if (gr != NULL)
321         return gr;
323     return app_id_to_group(gid, state);
326 struct group*
327 getgrnam(const char *name)
329     stubs_state_t*  state = __stubs_state();
330     unsigned        id;
332     if (state == NULL)
333         return NULL;
335     if (android_name_to_group(&state->group, name) != 0)
336         return &state->group;
338     return app_id_to_group( app_id_from_name(name), state );
342 struct netent* getnetbyname(const char *name)
344     fprintf(stderr, "FIX ME! implement getgrnam() %s:%d\n", __FILE__, __LINE__);
345     return NULL;
348 void endpwent(void)
352 struct mntent* getmntent(FILE* f)
354     fprintf(stderr, "FIX ME! implement getmntent() %s:%d\n", __FILE__, __LINE__);
355     return NULL;
358 char* ttyname(int fd)
360     fprintf(stderr, "FIX ME! implement ttyname() %s:%d\n", __FILE__, __LINE__);
361     return NULL;
364 struct netent *getnetbyaddr(uint32_t net, int type)
366     fprintf(stderr, "FIX ME! implement %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
367     return NULL;
370 struct protoent *getprotobyname(const char *name)
372     fprintf(stderr, "FIX ME! implement %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
373     return NULL;
376 struct protoent *getprotobynumber(int proto)
378     fprintf(stderr, "FIX ME! implement %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
379     return NULL;