summaryrefslogtreecommitdiffstats
path: root/qemu-props/qemu-props.c
blob: c80863a54be9d8682310f9733b79efef743e5bab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* this program is used to read a set of system properties and their values
 * from the emulator program and set them in the currently-running emulated
 * system. It does so by connecting to the 'boot-properties' qemud service.
 *
 * This program should be run as root and called from
 * /system/etc/init.goldfish.rc exclusively.
 */

#define LOG_TAG  "qemu-props"

#define DEBUG  1

#if DEBUG
#  include <cutils/log.h>
#  define  DD(...)    ALOGI(__VA_ARGS__)
#else
#  define  DD(...)    ((void)0)
#endif

#include <cutils/properties.h>
#include <unistd.h>
#include "qemud.h"

/* Name of the qemud service we want to connect to.
 */
#define  QEMUD_SERVICE  "boot-properties"

#define  MAX_TRIES      5

int  main(void)
{
    int  qemud_fd, count = 0;

    /* try to connect to the qemud service */
    {
        int  tries = MAX_TRIES;

        while (1) {
            qemud_fd = qemud_channel_open( "boot-properties" );
            if (qemud_fd >= 0)
                break;

            if (--tries <= 0) {
                DD("Could not connect after too many tries. Aborting");
                return 1;
            }

            DD("waiting 1s to wait for qemud.");
            sleep(1);
        }
    }

    DD("connected to '%s' qemud service.", QEMUD_SERVICE);

    /* send the 'list' command to the service */
    if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
        DD("could not send command to '%s' service", QEMUD_SERVICE);
        return 1;
    }

    /* read each system property as a single line from the service,
     * until exhaustion.
     */
    for (;;)
    {
#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
        DD("receiving..");
        char* q;
        char  temp[BUFF_SIZE];
        int   len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);

        /* lone NUL-byte signals end of properties */
        if (len < 0 || len > BUFF_SIZE-1 || temp[0] == '\0')
            break;

        temp[len] = '\0';  /* zero-terminate string */

        DD("received: %.*s", len, temp);

        /* separate propery name from value */
        q = strchr(temp, '=');
        if (q == NULL) {
            DD("invalid format, ignored.");
            continue;
        }
        *q++ = '\0';

        if (property_set(temp, q) < 0) {
            DD("could not set property '%s' to '%s'", temp, q);
        } else {
            count += 1;
        }
    }


    /* HACK start adbd periodically every minute, if adbd is already running, this is a no-op */
    for(;;) {
        usleep(60000000);
        char  temp[BUFF_SIZE];
        property_get("sys.boot_completed", temp, "");
        int is_boot_completed = (strncmp(temp, "1", 1) == 0) ? 1 : 0;
        if (is_boot_completed) {
            DD("start adbd ...");
            property_set("qemu.adbd", "start");
        } else {
            DD("skip starting adbd ...");
        }
    }

    /* finally, close the channel and exit */
    close(qemud_fd);
    DD("exiting (%d properties set).", count);
    return 0;
}