sync with latest
[sdk/emulator/qemu.git] / tizen / src / osutil-linux.c
1 /* 
2  * Emulator
3  *
4  * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: 
7  * SeokYeon Hwang <syeon.hwang@samsung.com>
8  * MunKyu Im <munkyu.im@samsung.com>
9  * GiWoong Kim <giwoong.kim@samsung.com>
10  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11  * HyunJun Son
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26  *
27  * Contributors:
28  * - S-Core Co., Ltd
29  *
30  */
31
32 /**
33   @file     osutil-linux.c
34   @brief    Collection of utilities for linux
35  */
36
37 #include "maru_common.h"
38 #include "osutil.h"
39 #include "emulator.h"
40 #include "debug_ch.h"
41 #include "maru_err_table.h"
42 #include "sdb.h"
43
44 #ifndef CONFIG_LINUX
45 #error
46 #endif
47
48 #include <string.h>
49 #include <unistd.h>
50 #include <sys/shm.h>
51 #include <sys/ipc.h>
52 #include <linux/version.h>
53 #include <sys/utsname.h>
54 #include <sys/sysinfo.h>
55
56 MULTI_DEBUG_CHANNEL(emulator, osutil);
57
58 extern char tizen_target_img_path[];
59 extern int tizen_base_port;
60 int g_shmid;
61 char *g_shared_memory;
62
63 void check_vm_lock_os(void)
64 {
65     int shm_id;
66     void *shm_addr;
67     uint32_t port;
68     int val;
69     struct shmid_ds shm_info;
70
71     for (port = 26100; port < 26200; port += 10) {
72         shm_id = shmget((key_t)port, 0, 0);
73         if (shm_id != -1) {
74             shm_addr = shmat(shm_id, (void *)0, 0);
75             if ((void *)-1 == shm_addr) {
76                 ERR("error occured at shmat()\n");
77                 break;
78             }
79
80             val = shmctl(shm_id, IPC_STAT, &shm_info);
81             if (val != -1) {
82                 INFO("count of process that use shared memory : %d\n",
83                     shm_info.shm_nattch);
84                 if ((shm_info.shm_nattch > 0) &&
85                     g_strcmp0(tizen_target_img_path, (char *)shm_addr) == 0) {
86                     if (check_port_bind_listen(port + 1) > 0) {
87                         shmdt(shm_addr);
88                         continue;
89                     }
90                     shmdt(shm_addr);
91                     maru_register_exit_msg(MARU_EXIT_UNKNOWN,
92                                         "Can not execute this VM.\n"
93                                         "The same name is running now.");
94                     exit(0);
95                 } else {
96                     shmdt(shm_addr);
97                 }
98             }
99         }
100     }
101 }
102
103 void make_vm_lock_os(void)
104 {
105     g_shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT);
106     if (g_shmid == -1) {
107         ERR("shmget failed\n");
108         perror("osutil-linux: ");
109         return;
110     }
111
112     g_shared_memory = shmat(g_shmid, (char *)0x00, 0);
113     if (g_shared_memory == (void *)-1) {
114         ERR("shmat failed\n");
115         perror("osutil-linux: ");
116         return;
117     }
118
119     g_sprintf(g_shared_memory, "%s", tizen_target_img_path);
120     INFO("shared memory key: %d value: %s\n",
121         tizen_base_port, (char *)g_shared_memory);
122
123     if (shmdt(g_shared_memory) == -1) {
124         ERR("shmdt failed\n");
125         perror("osutil-linux: ");
126     }
127 }
128
129 void set_bin_path_os(gchar * exec_argv)
130 {
131     gchar link_path[PATH_MAX] = { 0, };
132     char *file_name = NULL;
133
134     ssize_t len = readlink("/proc/self/exe", link_path, sizeof(link_path) - 1);
135
136     if (len < 0 || len > sizeof(link_path)) {
137         perror("set_bin_path error : ");
138         return;
139     }
140
141     link_path[len] = '\0';
142
143     file_name = g_strrstr(link_path, "/");
144     g_strlcpy(bin_path, link_path, strlen(link_path) - strlen(file_name) + 1);
145
146     g_strlcat(bin_path, "/", PATH_MAX);
147 }
148
149 void print_system_info_os(void)
150 {
151     INFO("* Linux\n");
152
153     /* depends on building */
154     INFO("* QEMU build machine linux kernel version : (%d, %d, %d)\n",
155             LINUX_VERSION_CODE >> 16,
156             (LINUX_VERSION_CODE >> 8) & 0xff,
157             LINUX_VERSION_CODE & 0xff);
158
159      /* depends on launching */
160     struct utsname host_uname_buf;
161     if (uname(&host_uname_buf) == 0) {
162         INFO("* Host machine uname : %s %s %s %s %s\n",
163             host_uname_buf.sysname, host_uname_buf.nodename,
164             host_uname_buf.release, host_uname_buf.version,
165             host_uname_buf.machine);
166     }
167
168     struct sysinfo sys_info;
169     if (sysinfo(&sys_info) == 0) {
170         INFO("* Total Ram : %llu kB, Free: %llu kB\n",
171             sys_info.totalram * (unsigned long long)sys_info.mem_unit / 1024,
172             sys_info.freeram * (unsigned long long)sys_info.mem_unit / 1024);
173     }
174
175     /* get linux distribution information */
176     INFO("* Linux distribution infomation :\n");
177     char lsb_release_cmd[MAXLEN] = "lsb_release -d -r -c >> ";
178     strcat(lsb_release_cmd, log_path);
179     if(system(lsb_release_cmd) < 0) {
180         INFO("system function command '%s' \
181             returns error !", lsb_release_cmd);
182     }
183
184     /* pci device description */
185     INFO("* PCI devices :\n");
186     char lspci_cmd[MAXLEN] = "lspci >> ";
187     strcat(lspci_cmd, log_path);
188     if(system(lspci_cmd) < 0) {
189         INFO("system function command '%s' \
190             returns error !", lspci_cmd);
191     }
192 }
193
194 static int get_auto_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
195 {
196     char type[MAXLEN];
197     char proxy[MAXLEN];
198     char line[MAXLEN];
199     FILE *fp_pacfile;
200     char *p = NULL;
201     FILE *output;
202     char buf[MAXLEN];
203
204     output = popen("gconftool-2 --get /system/proxy/autoconfig_url", "r");
205     if(fscanf(output, "%s", buf) > 0) {
206         INFO("pac address: %s\n", buf);
207         download_url(buf);
208     }
209     pclose(output);
210     fp_pacfile = fopen(pac_tempfile, "r");
211     if(fp_pacfile != NULL) {
212         while(fgets(line, MAXLEN, fp_pacfile) != NULL) {
213             if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
214                 INFO("line found %s", line);
215                 sscanf(line, "%*[^\"]\"%s %s", type, proxy);
216             }
217         }
218
219         if(g_str_has_prefix(type, DIRECT)) {
220             INFO("auto proxy is set to direct mode\n");
221             fclose(fp_pacfile);
222         }
223         else if(g_str_has_prefix(type, PROXY)) {
224             INFO("auto proxy is set to proxy mode\n");
225             INFO("type: %s, proxy: %s\n", type, proxy);
226             p = strtok(proxy, "\";");
227             if(p != NULL) {
228                 INFO("auto proxy to set: %s\n",p);
229                 strcpy(http_proxy, p);
230                 strcpy(https_proxy, p);
231                 strcpy(ftp_proxy, p);
232                 strcpy(socks_proxy, p);
233             }
234             fclose(fp_pacfile);
235         }
236         else
237         {
238             ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
239             fclose(fp_pacfile);
240         }
241     } 
242     else {
243         ERR("fail to get pacfile fp\n");
244         return -1;
245     }
246
247     remove(pac_tempfile);
248     return 0;
249 }
250
251 static void get_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
252 {
253     char buf[MAXLEN] = {0,};
254     char buf_port[MAXPORTLEN] = {0,};
255     char buf_proxy[MAXLEN] = {0,};
256     char *buf_proxy_bak;
257     char *proxy;
258     FILE *output;
259     int MAXPROXYLEN = MAXLEN + MAXPORTLEN;
260
261     output = popen("gconftool-2 --get /system/http_proxy/host", "r");
262     if(fscanf(output, "%s", buf) > 0) {
263         snprintf(buf_proxy, MAXLEN, "%s", buf);
264     }
265     pclose(output);
266     
267     output = popen("gconftool-2 --get /system/http_proxy/port", "r");
268     if(fscanf(output, "%s", buf_port) <= 0) {
269         //for abnormal case: if can't find the key of http port, get from environment value.
270         buf_proxy_bak = getenv("http_proxy");
271         INFO("http_proxy from env: %s\n", buf_proxy_bak);
272         if(buf_proxy_bak != NULL) {
273             proxy = malloc(MAXLEN);
274             remove_string(buf_proxy_bak, proxy, HTTP_PREFIX);
275             strncpy(http_proxy, proxy, strlen(proxy)-1);
276             INFO("final http_proxy value: %s\n", http_proxy);
277             free(proxy);
278         }
279         else {
280             INFO("http_proxy is not set on env.\n");
281             pclose(output);
282             return;
283         }
284
285     }
286     else {
287         snprintf(http_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf_port);
288         memset(buf_proxy, 0, MAXLEN);
289         INFO("http_proxy: %s\n", http_proxy);
290     }
291     pclose(output);
292
293     memset(buf, 0, MAXLEN);
294
295     output = popen("gconftool-2 --get /system/proxy/secure_host", "r");
296     if(fscanf(output, "%s", buf) > 0) {
297         snprintf(buf_proxy, MAXLEN, "%s", buf);
298     }
299     pclose(output);
300
301     output = popen("gconftool-2 --get /system/proxy/secure_port", "r");
302     if(fscanf(output, "%s", buf) > 0) {
303         snprintf(https_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
304     }
305     pclose(output);
306     memset(buf, 0, MAXLEN);
307     memset(buf_proxy, 0, MAXLEN);
308     INFO("https_proxy : %s\n", https_proxy);
309
310     output = popen("gconftool-2 --get /system/proxy/ftp_host", "r");
311     if(fscanf(output, "%s", buf) > 0) {
312         snprintf(buf_proxy, MAXLEN, "%s", buf);
313     }
314     pclose(output);
315
316     output = popen("gconftool-2 --get /system/proxy/ftp_port", "r");
317     if(fscanf(output, "%s", buf) > 0) {
318         snprintf(ftp_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
319     }
320     pclose(output);
321     memset(buf, 0, MAXLEN);
322     memset(buf_proxy, 0, MAXLEN);
323     INFO("ftp_proxy : %s\n", ftp_proxy);
324
325     output = popen("gconftool-2 --get /system/proxy/socks_host", "r");
326     if(fscanf(output, "%s", buf) > 0) {
327         snprintf(buf_proxy, MAXLEN, "%s", buf);
328     }
329     pclose(output);
330
331     output = popen("gconftool-2 --get /system/proxy/socks_port", "r");
332     if(fscanf(output, "%s", buf) > 0) {
333         snprintf(socks_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
334     }
335     pclose(output);
336     INFO("socks_proxy : %s\n", socks_proxy);
337 }
338
339
340 void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
341 {
342     char buf[MAXLEN];
343     FILE *output;
344
345     output = popen("gconftool-2 --get /system/proxy/mode", "r");
346     if(fscanf(output, "%s", buf) > 0) {
347         //priority : auto > manual > none       
348         if (strcmp(buf, "auto") == 0) {
349             INFO("AUTO PROXY MODE\n");
350             get_auto_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
351         }
352         else if (strcmp(buf, "manual") == 0) {
353             INFO("MANUAL PROXY MODE\n");
354             get_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
355         }
356         else if (strcmp(buf, "none") == 0) {
357             INFO("DIRECT PROXY MODE\n");
358         }
359     }
360     pclose(output);
361 }