upload tizen1.0 source
[pkgs/n/native-installer.git] / common / NativeInstallerUtil.c
1 /*
2  * rpm-installer
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23
24
25
26
27 #include <string.h>
28 #include <stdarg.h>
29 #include <sys/wait.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <wait.h>
33 #include <stdio.h>
34 #include <ctype.h>              /* for isspace () */
35 #include <string.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40
41 #include <syslog.h>
42 #include "native_installer_util.h"
43
44 #include <dlog.h>
45
46 #define LOG_TAG                         "nativeinstaller"
47 #define LOG_TAG_BACKEND         "native-backend"
48 #define LOG_TAG_FRONTEND        "native-frontend"
49
50 int logging = 0x0004;
51 #ifdef LOG_IN_FILE
52 #define NATIVE_INSTALLER_LOG_FILE "/tmp/native-installer"
53 FILE *logfile = NULL;
54 #endif
55
56 /**
57  * This is intended to be a faster splitter, it does not use dynamic
58  *  memories. Input is changed to insert nulls at each token location. 
59  */
60 int _tok_split_string(char tok, char *input, char **list, unsigned long listmax)
61 {
62         /* Strip any leading spaces */
63         char *Start = input;
64         char *Stop = Start + strlen(Start);
65         for (; *Start != 0 && isspace(*Start) != 0; Start++) ;
66
67         unsigned long Count = 0;
68         char *Pos = Start;
69         while (Pos != Stop) {
70                 /* Skip to the next Token */
71                 for (; Pos != Stop && *Pos != tok; Pos++) ;
72
73                 /* Back remove spaces */
74                 char *End = Pos;
75                 for (; 
76                      End > Start && (End[-1] == tok || isspace(End[-1]) != 0);
77                      End--) ;
78
79                 *End = 0;
80
81                 list[Count++] = Start;
82                 if (Count >= listmax) {
83                         list[Count - 1] = 0;
84                         return -1;
85                 }
86                 /* Advance pos */
87                 for (;
88                      Pos != Stop && (*Pos == tok || isspace(*Pos) != 0
89                                      || *Pos == 0); Pos++) ;
90
91                 Start = Pos;
92         }
93
94         list[Count] = 0;
95         return 0;
96 }
97
98 void _d_msg_init(char *program)
99 {
100         if (logging == 0)
101                 return;
102
103 #ifdef LOG_IN_FILE
104         char logfilename[64];
105         char buffer[256] = { 0 };
106         snprintf(logfilename, 64, "%s-%s", NATIVE_INSTALLER_LOG_FILE, program);
107         logfile = fopen(logfilename, "a+");
108
109         if (logfile == NULL)
110                 printf("Error opening log file\n");
111         else {
112                 snprintf(buffer, 64, "\nLog File %s Created", logfilename);
113                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
114                 snprintf(buffer, 64, "\nLog Started\n");
115                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
116         }
117 #endif
118 }
119
120 void _d_msg_deinit()
121 {
122         if (logging == 0)
123                 return;
124
125 #ifdef LOG_IN_FILE
126         if (logfile != NULL)
127                 fclose(logfile);
128 #endif
129 }
130
131 void _print_msg(int type, int exetype, char *format, ...)
132 {
133         char buffer[1024] = { 0 };
134         char tbuffer[1024] = { 0 };
135         int nbuffer;
136         va_list args;
137         va_start(args, format);
138         nbuffer = vsnprintf(tbuffer, 1024, format, args);
139         va_end(args);
140
141         switch (type) {
142         case DEBUG_ERR:
143                 LOG(LOG_ERROR, LOG_TAG, tbuffer);
144                 break;
145         case DEBUG_RESULT:
146                 LOG(LOG_WARN, LOG_TAG, tbuffer);
147                 break;
148         case DEBUG_INFO:
149                 LOG(LOG_DEBUG, LOG_TAG, tbuffer);
150         default:
151                 break;
152         }
153
154         if (logging == 0)
155                 return;
156
157         if (DEBUG_ERR == (logging & type)) {
158                 nbuffer = snprintf(buffer, 1024, "ERROR:%s", tbuffer);
159                 vfprintf(stderr, format, args);
160         } else if (DEBUG_INFO == (logging & type)) {
161                 nbuffer = snprintf(buffer, 1024, "INFO:%s", tbuffer);
162                 vfprintf(stdout, format, args);
163         } else if (DEBUG_RESULT == (logging & type)) {
164                 nbuffer = snprintf(buffer, 1024, "RESULT:%s", tbuffer);
165                 vfprintf(stdout, format, args);
166         } else {
167                 return;
168         }
169
170 #ifdef LOG_IN_FILE
171         if (logfile != NULL)
172                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
173 #endif                          /*LOG_IN_FILE */
174 }
175
176 /* Like system(3), but with error messages printed if the fork fails
177    or if the child process dies due to an uncaught signal. Also, the
178    return value is a bit simpler:
179
180    -1 if there was any problem
181    Otherwise, the 8-bit return value of the program ala WEXITSTATUS
182    as defined in <sys/wait.h>.
183    */
184 int _xsystem(const char *argv[])
185 {
186         int status;
187         pid_t pid;
188         pid = vfork();
189         switch (pid) {
190         case -1:
191                 perror("fork failed");
192                 return -1;
193         case 0:
194                 /* child */
195                 execvp(argv[0], (char *const *)argv);
196                 _exit(-1);
197         default:
198                 /* parent */
199                 break;
200         }
201
202         d_msg_backend(DEBUG_INFO, "parent\n");
203         if (waitpid(pid, &status, 0) == -1) {
204                 perror("waitpid failed");
205                 return -1;
206         }
207
208         if (WIFSIGNALED(status)) {
209                 perror("signal");
210                 return -1;
211         }
212
213         if (!WIFEXITED(status)) {
214                 /* shouldn't happen */
215                 perror("should not happen");
216                 return -1;
217         }
218
219         return WEXITSTATUS(status);
220 }
221
222 char *_substring(const char *str, size_t begin, size_t len)
223 {
224         if (str == 0 || strlen(str) == 0 || strlen(str) < begin
225             || strlen(str) < (begin + len))
226                 return 0;
227         return strndup(str + begin, len);
228 }
229
230 void _error_no_to_string(int errnumber, char **errstr)
231 {
232         if (errstr == NULL)
233                 return;
234         switch (errnumber) {
235         case NATIVEINSTALLER_SUCCESS:
236                 *errstr = NATIVEINSTALLER_SUCCESS_STR;
237                 break;
238         case NATIVEINSTALLER_ERR_WRONG_PARAM:
239                 *errstr = NATIVEINSTALLER_ERR_WRONG_PARAM_STR;
240                 break;
241         case NATIVEINSTALLER_ERR_DBUS_PROBLEM:
242                 *errstr = NATIVEINSTALLER_ERR_DBUS_PROBLEM_STR;
243                 break;
244         case NATIVEINSTALLER_ERR_NOT_ENOUGH_MEMORY:
245                 *errstr = NATIVEINSTALLER_ERR_NOT_ENOUGH_MEMORY_STR;
246                 break;
247         case NATIVEINSTALLER_ERR_NO_MANIFEST:
248                 *errstr = NATIVEINSTALLER_ERR_NO_MANIFEST_STR;
249                 break;
250         case NATIVEINSTALLER_ERR_PACKAGE_EXIST:
251                 *errstr = NATIVEINSTALLER_ERR_PACKAGE_EXIST_STR;
252                 break;
253         case NATIVEINSTALLER_ERR_PACKAGE_NOT_INSTALLED:
254                 *errstr = NATIVEINSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR;
255                 break;
256         case NATIVEINSTALLER_ERR_RESOURCE_BUSY:
257                 *errstr = NATIVEINSTALLER_ERR_RESOURCE_BUSY_STR;
258                 break;
259         case NATIVEINSTALLER_ERR_UNKNOWN:
260                 *errstr = NATIVEINSTALLER_ERR_UNKNOWN_STR;
261                 break;
262         case NATIVEINSTALLER_ERR_PKG_NOT_FOUND:
263                 *errstr = NATIVEINSTALLER_ERR_PKG_NOT_FOUND_STR;
264                 break;
265         case NATIVEINSTALLER_ERR_NOT_SUPPOTED_VERSION:
266                 *errstr = NATIVEINSTALLER_ERR_NOT_SUPPOTED_VERSION_STR;
267                 break;
268         case NATIVEINSTALLER_ERR_NO_DEB_FILE:
269                 *errstr = NATIVEINSTALLER_ERR_NO_DEB_FILE_STR;
270                 break;
271         case NATIVEINSTALLER_ERR_DB_ACCESS_FAILED:
272                 *errstr = NATIVEINSTALLER_ERR_DB_ACCESS_FAILED_STR;
273                 break;
274         case NATIVEINSTALLER_ERR_DPKG_OPERATION_FAILED:
275                 *errstr = NATIVEINSTALLER_ERR_DPKG_OPERATION_FAILED_STR;
276                 break;
277         case NATIVEINSTALLER_PACKAGE_NOT_UPGRADED:
278                 *errstr = NATIVEINSTALLER_PACKAGE_NOT_UPGRADED_STR;
279                 break;
280         case NATIVEINSTALLER_ERR_CLEAR_DATA_FAILED:
281                 *errstr = NATIVEINSTALLER_ERR_CLEAR_DATA_FAILED_STR;
282                 break;
283         default:
284                 *errstr = NATIVEINSTALLER_ERR_UNKNOWN_STR;
285                 break;
286         }
287 }
288
289 int _string_to_error_no(char *errstr)
290 {
291         int errnumber = NATIVEINSTALLER_ERR_UNKNOWN;
292         if (errstr == NULL)
293                 return errnumber;
294
295         if (strcmp(errstr, NATIVEINSTALLER_SUCCESS_STR) == 0)
296                 errnumber = NATIVEINSTALLER_SUCCESS;
297         else if (strcmp(errstr, NATIVEINSTALLER_ERR_WRONG_PARAM_STR) == 0)
298                 errnumber = NATIVEINSTALLER_ERR_WRONG_PARAM;
299         else if (strcmp(errstr, NATIVEINSTALLER_ERR_DBUS_PROBLEM_STR) == 0)
300                 errnumber = NATIVEINSTALLER_ERR_DBUS_PROBLEM;
301         else if (strcmp(errstr, NATIVEINSTALLER_ERR_NOT_ENOUGH_MEMORY_STR) == 0)
302                 errnumber = NATIVEINSTALLER_ERR_NOT_ENOUGH_MEMORY;
303         else if (strcmp(errstr, NATIVEINSTALLER_ERR_NO_MANIFEST_STR) == 0)
304                 errnumber = NATIVEINSTALLER_ERR_NO_MANIFEST;
305         else if (strcmp(errstr, NATIVEINSTALLER_ERR_PACKAGE_EXIST_STR) == 0)
306                 errnumber = NATIVEINSTALLER_ERR_PACKAGE_EXIST;
307         else if (strcmp(errstr, NATIVEINSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR)
308                  == 0)
309                 errnumber = NATIVEINSTALLER_ERR_PACKAGE_NOT_INSTALLED;
310         else if (strcmp(errstr, NATIVEINSTALLER_ERR_RESOURCE_BUSY_STR) == 0)
311                 errnumber = NATIVEINSTALLER_ERR_RESOURCE_BUSY;
312         else if (strcmp(errstr, NATIVEINSTALLER_ERR_UNKNOWN_STR) == 0)
313                 errnumber = NATIVEINSTALLER_ERR_UNKNOWN;
314         else if (strcmp(errstr, NATIVEINSTALLER_ERR_PKG_NOT_FOUND_STR) == 0)
315                 errnumber = NATIVEINSTALLER_ERR_PKG_NOT_FOUND;
316         else if (strcmp(errstr, NATIVEINSTALLER_ERR_NOT_SUPPOTED_VERSION_STR) ==
317                  0)
318                 errnumber = NATIVEINSTALLER_ERR_NOT_SUPPOTED_VERSION;
319         else if (strcmp(errstr, NATIVEINSTALLER_ERR_NO_DEB_FILE_STR) == 0)
320                 errnumber = NATIVEINSTALLER_ERR_NO_DEB_FILE;
321         else if (strcmp(errstr, NATIVEINSTALLER_ERR_DB_ACCESS_FAILED_STR) == 0)
322                 errnumber = NATIVEINSTALLER_ERR_DB_ACCESS_FAILED;
323         else if (strcmp(errstr, NATIVEINSTALLER_ERR_DPKG_OPERATION_FAILED_STR)
324                  == 0)
325                 errnumber = NATIVEINSTALLER_ERR_DPKG_OPERATION_FAILED;
326         else if (strcmp(errstr, NATIVEINSTALLER_PACKAGE_NOT_UPGRADED_STR) == 0)
327                 errnumber = NATIVEINSTALLER_PACKAGE_NOT_UPGRADED;
328         else if (strcmp(errstr, NATIVEINSTALLER_ERR_CLEAR_DATA_FAILED_STR) == 0)
329                 errnumber = NATIVEINSTALLER_ERR_CLEAR_DATA_FAILED;
330         return errnumber;
331 }
332