Home | History | Annotate | Download | only in init
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <poll.h>
     18 #include <fcntl.h>
     19 #include <string.h>
     20 #include <stdlib.h>
     21 #include <stdio.h>
     22 #include <ctype.h>
     23 #include <private/android_filesystem_config.h>
     24 
     25 #include "ueventd.h"
     26 #include "log.h"
     27 #include "util.h"
     28 #include "devices.h"
     29 #include "ueventd_parser.h"
     30 
     31 static char hardware[32];
     32 static unsigned revision = 0;
     33 
     34 int ueventd_main(int argc, char **argv)
     35 {
     36     struct pollfd ufd;
     37     int nr;
     38     char tmp[32];
     39 
     40     open_devnull_stdio();
     41     log_init();
     42 
     43     INFO("starting ueventd\n");
     44 
     45     get_hardware_name(hardware, &revision);
     46 
     47     ueventd_parse_config_file("/ueventd.rc");
     48 
     49     snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
     50     ueventd_parse_config_file(tmp);
     51 
     52     device_init();
     53 
     54     ufd.events = POLLIN;
     55     ufd.fd = get_device_fd();
     56 
     57     while(1) {
     58         ufd.revents = 0;
     59         nr = poll(&ufd, 1, -1);
     60         if (nr <= 0)
     61             continue;
     62         if (ufd.revents == POLLIN)
     63                handle_device_fd();
     64     }
     65 }
     66 
     67 static int get_android_id(const char *id)
     68 {
     69     unsigned int i;
     70     for (i = 0; i < ARRAY_SIZE(android_ids); i++)
     71         if (!strcmp(id, android_ids[i].name))
     72             return android_ids[i].aid;
     73     return 0;
     74 }
     75 
     76 void set_device_permission(int nargs, char **args)
     77 {
     78     char *name;
     79     char *attr = 0;
     80     mode_t perm;
     81     uid_t uid;
     82     gid_t gid;
     83     int prefix = 0;
     84     char *endptr;
     85     int ret;
     86     char *tmp = 0;
     87 
     88     if (nargs == 0)
     89         return;
     90 
     91     if (args[0][0] == '#')
     92         return;
     93 
     94     name = args[0];
     95 
     96     if (!strncmp(name,"/sys/", 5) && (nargs == 5)) {
     97         INFO("/sys/ rule %s %s\n",args[0],args[1]);
     98         attr = args[1];
     99         args++;
    100         nargs--;
    101     }
    102 
    103     if (nargs != 4) {
    104         ERROR("invalid line ueventd.rc line for '%s'\n", args[0]);
    105         return;
    106     }
    107 
    108     /* If path starts with mtd@ lookup the mount number. */
    109     if (!strncmp(name, "mtd@", 4)) {
    110         int n = mtd_name_to_number(name + 4);
    111         if (n >= 0)
    112             asprintf(&tmp, "/dev/mtd/mtd%d", n);
    113         name = tmp;
    114     } else {
    115         int len = strlen(name);
    116         if (name[len - 1] == '*') {
    117             prefix = 1;
    118             name[len - 1] = '\0';
    119         }
    120     }
    121 
    122     perm = strtol(args[1], &endptr, 8);
    123     if (!endptr || *endptr != '\0') {
    124         ERROR("invalid mode '%s'\n", args[1]);
    125         free(tmp);
    126         return;
    127     }
    128 
    129     ret = get_android_id(args[2]);
    130     if (ret < 0) {
    131         ERROR("invalid uid '%s'\n", args[2]);
    132         free(tmp);
    133         return;
    134     }
    135     uid = ret;
    136 
    137     ret = get_android_id(args[3]);
    138     if (ret < 0) {
    139         ERROR("invalid gid '%s'\n", args[3]);
    140         free(tmp);
    141         return;
    142     }
    143     gid = ret;
    144 
    145     add_dev_perms(name, attr, perm, uid, gid, prefix);
    146     free(tmp);
    147 }
    148