Tizen 2.1 base
[platform/core/base/rpm-installer.git] / common / rpm-installer-util.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 #include <string.h>
24 #include <stdarg.h>
25 #include <sys/wait.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <wait.h>
29 #include <stdio.h>
30 #include <ctype.h>              /* for isspace () */
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36
37 #include <syslog.h>
38 #include "rpm-installer-util.h"
39
40 #include <dlog.h>
41
42 #define LOG_TAG                         "rpminstaller"
43
44 int logging = 0x0004;
45 #ifdef LOG_IN_FILE
46 #define RPM_INSTALLER_LOG_FILE "/tmp/rpm-installer"
47 FILE *logfile = NULL;
48 #endif
49
50 /**
51  * This is intended to be a faster splitter, it does not use dynamic
52  *  memories. Input is changed to insert nulls at each token location.
53  */
54 int _ri_tok_split_string(char tok, char *input, char **list,
55                          unsigned long listmax)
56 {
57         /* Strip any leading spaces */
58         char *start = input;
59         char *stop = start + strlen(start);
60         for (; *start != 0 && isspace(*start) != 0; start++) ;
61
62         unsigned long count = 0;
63         char *pos = start;
64         while (pos != stop) {
65                 /* Skip to the next Token */
66                 for (; pos != stop && *pos != tok; pos++) ;
67
68                 /* Back remove spaces */
69                 char *end = pos;
70                 for (;
71                      end > start && (end[-1] == tok || isspace(end[-1]) != 0);
72                      end--) ;
73
74                 *end = 0;
75
76                 list[count++] = start;
77                 if (count >= listmax) {
78                         list[count - 1] = 0;
79                         return -1;
80                 }
81                 /* Advance pos */
82                 for (;
83                      pos != stop && (*pos == tok || isspace(*pos) != 0
84                                      || *pos == 0); pos++) ;
85
86                 start = pos;
87         }
88
89         list[count] = 0;
90         return 0;
91 }
92
93 void _d_msg_init(char *program)
94 {
95         if (logging == 0)
96                 return;
97
98 #ifdef LOG_IN_FILE
99         char logfilename[64] = { 0, };
100         char buffer[256] = { 0 };
101         snprintf(logfilename, 64, "%s-%s", RPM_INSTALLER_LOG_FILE, program);
102         logfile = fopen(logfilename, "a+");
103
104         if (logfile == NULL)
105                 printf("Error opening log file\n");
106         else {
107                 snprintf(buffer, 64, "\nLog File %s Created", logfilename);
108                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
109                 snprintf(buffer, 64, "\nLog Started\n");
110                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
111         }
112 #endif
113 }
114
115 void _d_msg_deinit()
116 {
117         if (logging == 0)
118                 return;
119
120 #ifdef LOG_IN_FILE
121         if (logfile != NULL)
122                 fclose(logfile);
123 #endif
124 }
125
126 void _print_msg(int type, int exetype, char *format, ...)
127 {
128         char buffer[1024] = { 0 };
129         char tbuffer[1024] = { 0 };
130         int nbuffer = 0;
131         va_list args;
132         va_start(args, format);
133         nbuffer = vsnprintf(tbuffer, 1024, format, args);
134         va_end(args);
135
136         switch (type) {
137         case DEBUG_ERR:
138                 LOG(LOG_ERROR, LOG_TAG, tbuffer);
139                 break;
140         case DEBUG_RESULT:
141                 LOG(LOG_WARN, LOG_TAG, tbuffer);
142                 break;
143         case DEBUG_INFO:
144                 LOG(LOG_DEBUG, LOG_TAG, tbuffer);
145         default:
146                 break;
147         }
148
149         if (logging == 0)
150                 return;
151
152         if (DEBUG_ERR == (logging & type)) {
153                 nbuffer = snprintf(buffer, 1024, "ERROR:%s", tbuffer);
154                 vfprintf(stderr, format, args);
155         } else if (DEBUG_INFO == (logging & type)) {
156                 nbuffer = snprintf(buffer, 1024, "INFO:%s", tbuffer);
157                 vfprintf(stdout, format, args);
158         } else if (DEBUG_RESULT == (logging & type)) {
159                 nbuffer = snprintf(buffer, 1024, "RESULT:%s", tbuffer);
160                 vfprintf(stdout, format, args);
161         } else {
162                 return;
163         }
164
165 #ifdef LOG_IN_FILE
166         if (logfile != NULL)
167                 fwrite(buffer, sizeof(char), strlen(buffer), logfile);
168 #endif                          /*LOG_IN_FILE */
169 }
170
171 /* Like system(3), but with error messages printed if the fork fails
172    or if the child process dies due to an uncaught signal. Also, the
173    return value is a bit simpler:
174
175    -1 if there was any problem
176    Otherwise, the 8-bit return value of the program ala WEXITSTATUS
177    as defined in <sys/wait.h>.
178    */
179 int _ri_xsystem(const char *argv[])
180 {
181         int status;
182         pid_t pid;
183         pid = vfork();
184         switch (pid) {
185         case -1:
186                 perror("fork failed");
187                 return -1;
188         case 0:
189                 /* child */
190                 execvp(argv[0], (char *const *)argv);
191                 _exit(-1);
192         default:
193                 /* parent */
194                 break;
195         }
196
197         _d_msg(DEBUG_INFO, "parent\n");
198         if (waitpid(pid, &status, 0) == -1) {
199                 perror("waitpid failed");
200                 return -1;
201         }
202
203         if (WIFSIGNALED(status)) {
204                 perror("signal");
205                 return -1;
206         }
207
208         if (!WIFEXITED(status)) {
209                 /* shouldn't happen */
210                 perror("should not happen");
211                 return -1;
212         }
213
214         return WEXITSTATUS(status);
215 }
216
217 char *_ri_substring(const char *str, size_t begin, size_t len)
218 {
219         if (str == 0 || strlen(str) == 0 || strlen(str) < (begin + len))
220                 return 0;
221         return strndup(str + begin, len);
222 }
223
224 void _ri_error_no_to_string(int errnumber, char **errstr)
225 {
226         if (errstr == NULL)
227                 return;
228         switch (errnumber) {
229         case RPM_INSTALLER_SUCCESS:
230                 *errstr = RPM_INSTALLER_SUCCESS_STR;
231                 break;
232         case RPM_INSTALLER_ERR_WRONG_PARAM:
233                 *errstr = RPM_INSTALLER_ERR_WRONG_PARAM_STR;
234                 break;
235         case RPM_INSTALLER_ERR_DBUS_PROBLEM:
236                 *errstr = RPM_INSTALLER_ERR_DBUS_PROBLEM_STR;
237                 break;
238         case RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY:
239                 *errstr = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY_STR;
240                 break;
241         case RPM_INSTALLER_ERR_PACKAGE_EXIST:
242                 *errstr = RPM_INSTALLER_ERR_PACKAGE_EXIST_STR;
243                 break;
244         case RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED:
245                 *errstr = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR;
246                 break;
247         case RPM_INSTALLER_ERR_RESOURCE_BUSY:
248                 *errstr = RPM_INSTALLER_ERR_RESOURCE_BUSY_STR;
249                 break;
250         case RPM_INSTALLER_ERR_UNKNOWN:
251                 *errstr = RPM_INSTALLER_ERR_UNKNOWN_STR;
252                 break;
253         case RPM_INSTALLER_ERR_PKG_NOT_FOUND:
254                 *errstr = RPM_INSTALLER_ERR_PKG_NOT_FOUND_STR;
255                 break;
256         case RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION:
257                 *errstr = RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION_STR;
258                 break;
259         case RPM_INSTALLER_ERR_NO_RPM_FILE:
260                 *errstr = RPM_INSTALLER_ERR_NO_RPM_FILE_STR;
261                 break;
262         case RPM_INSTALLER_ERR_DB_ACCESS_FAILED:
263                 *errstr = RPM_INSTALLER_ERR_DB_ACCESS_FAILED_STR;
264                 break;
265         case RPM_INSTALLER_ERR_RPM_OPERATION_FAILED:
266                 *errstr = RPM_INSTALLER_ERR_RPM_OPERATION_FAILED_STR;
267                 break;
268         case RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED:
269                 *errstr = RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED_STR;
270                 break;
271         case RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS:
272                 *errstr = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS_STR;
273                 break;
274         case RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED:
275                 *errstr = RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED_STR;
276                 break;
277         case RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED:
278                 *errstr = RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED_STR;
279                 break;
280         case RPM_INSTALLER_ERR_CLEAR_DATA_FAILED:
281                 *errstr = RPM_INSTALLER_ERR_CLEAR_DATA_FAILED_STR;
282                 break;
283         case RPM_INSTALLER_ERR_INTERNAL:
284                 *errstr = RPM_INSTALLER_ERR_INTERNAL_STR;
285                 break;
286         case RPM_INSTALLER_ERR_NO_MANIFEST:
287                 *errstr = RPM_INSTALLER_ERR_NO_MANIFEST_STR;
288                 break;
289         case RPM_INSTALLER_ERR_INVALID_MANIFEST:
290                 *errstr = RPM_INSTALLER_ERR_INVALID_MANIFEST_STR;
291                 break;
292         default:
293                 *errstr = RPM_INSTALLER_ERR_UNKNOWN_STR;
294                 break;
295         }
296 }
297
298 int _ri_string_to_error_no(char *errstr)
299 {
300         int errnumber = RPM_INSTALLER_ERR_UNKNOWN;
301         if (errstr == NULL)
302                 return errnumber;
303
304         if (strcmp(errstr, RPM_INSTALLER_SUCCESS_STR) == 0)
305                 errnumber = RPM_INSTALLER_SUCCESS;
306         else if (strcmp(errstr, RPM_INSTALLER_ERR_WRONG_PARAM_STR) == 0)
307                 errnumber = RPM_INSTALLER_ERR_WRONG_PARAM;
308         else if (strcmp(errstr, RPM_INSTALLER_ERR_DBUS_PROBLEM_STR) == 0)
309                 errnumber = RPM_INSTALLER_ERR_DBUS_PROBLEM;
310         else if (strcmp(errstr, RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY_STR) == 0)
311                 errnumber = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
312         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_EXIST_STR) == 0)
313                 errnumber = RPM_INSTALLER_ERR_PACKAGE_EXIST;
314         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR)
315                  == 0)
316                 errnumber = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
317         else if (strcmp(errstr, RPM_INSTALLER_ERR_RESOURCE_BUSY_STR) == 0)
318                 errnumber = RPM_INSTALLER_ERR_RESOURCE_BUSY;
319         else if (strcmp(errstr, RPM_INSTALLER_ERR_UNKNOWN_STR) == 0)
320                 errnumber = RPM_INSTALLER_ERR_UNKNOWN;
321         else if (strcmp(errstr, RPM_INSTALLER_ERR_PKG_NOT_FOUND_STR) == 0)
322                 errnumber = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
323         else if (strcmp(errstr, RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION_STR) ==
324                  0)
325                 errnumber = RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION;
326         else if (strcmp(errstr, RPM_INSTALLER_ERR_NO_RPM_FILE_STR) == 0)
327                 errnumber = RPM_INSTALLER_ERR_NO_RPM_FILE;
328         else if (strcmp(errstr, RPM_INSTALLER_ERR_DB_ACCESS_FAILED_STR) == 0)
329                 errnumber = RPM_INSTALLER_ERR_DB_ACCESS_FAILED;
330         else if (strcmp(errstr, RPM_INSTALLER_ERR_RPM_OPERATION_FAILED_STR)
331                  == 0)
332                 errnumber = RPM_INSTALLER_ERR_RPM_OPERATION_FAILED;
333         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED_STR) ==
334                  0)
335                 errnumber = RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
336         else if (strcmp(errstr, RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS_STR) ==
337                  0)
338                 errnumber = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
339         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED_STR) == 0)
340                 errnumber = RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED;
341         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED_STR) == 0)
342                 errnumber = RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED;
343         else if (strcmp(errstr, RPM_INSTALLER_ERR_CLEAR_DATA_FAILED_STR) == 0)
344                 errnumber = RPM_INSTALLER_ERR_CLEAR_DATA_FAILED;
345         else if (strcmp(errstr, RPM_INSTALLER_ERR_INTERNAL_STR) == 0)
346                 errnumber = RPM_INSTALLER_ERR_INTERNAL;
347         else if (strcmp(errstr, RPM_INSTALLER_ERR_NO_MANIFEST_STR) == 0)
348                 errnumber = RPM_INSTALLER_ERR_NO_MANIFEST;
349         else if (strcmp(errstr, RPM_INSTALLER_ERR_INVALID_MANIFEST_STR) == 0)
350                 errnumber = RPM_INSTALLER_ERR_INVALID_MANIFEST;
351         else
352                 _d_msg(DEBUG_ERR, "Unsupported Error\n");
353         return errnumber;
354 }