2 * Copyright (C) 2012 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "imv_os_database.h"
18 #include <utils/debug.h>
22 typedef struct private_imv_os_database_t private_imv_os_database_t
;
25 * Private data of a imv_os_database_t object.
28 struct private_imv_os_database_t
{
31 * Public imv_os_database_t interface.
33 imv_os_database_t
public;
42 METHOD(imv_os_database_t
, check_packages
, status_t
,
43 private_imv_os_database_t
*this, imv_os_state_t
*state
,
44 enumerator_t
*package_enumerator
)
46 char *product
, *package
, *release
, *cur_release
;
48 chunk_t os_name
, os_version
, name
, version
;
50 size_t os_version_len
;
51 os_package_state_t package_state
;
53 int count
= 0, count_ok
= 0, count_no_match
= 0, count_blacklist
= 0;
55 status_t status
= SUCCESS
;
58 state
->get_info(state
, &os_type
, &os_name
, &os_version
);
60 if (os_type
== OS_TYPE_ANDROID
)
62 /*no package dependency on Android version */
63 product
= strdup(enum_to_name(os_type_names
, os_type
));
67 /* remove appended platform info */
68 pos
= memchr(os_version
.ptr
, ' ', os_version
.len
);
69 os_version_len
= pos ?
(pos
- os_version
.ptr
) : os_version
.len
;
70 product
= malloc(os_name
.len
+ 1 + os_version_len
+ 1);
71 sprintf(product
, "%.*s %.*s", os_name
.len
, os_name
.ptr
,
72 os_version_len
, os_version
.ptr
);
74 DBG1(DBG_IMV
, "processing installed '%s' packages", product
);
76 /* Get primary key of product */
77 e
= this->db
->query(this->db
,
78 "SELECT id FROM products WHERE name = ?",
79 DB_TEXT
, product
, DB_INT
);
85 if (!e
->enumerate(e
, &pid
))
93 while (package_enumerator
->enumerate(package_enumerator
, &name
, &version
))
95 /* Convert package name chunk to a string */
96 package
= strndup(name
.ptr
, name
.len
);
99 /* Get primary key of package */
100 e
= this->db
->query(this->db
,
101 "SELECT id FROM packages WHERE name = ?",
102 DB_TEXT
, package
, DB_INT
);
109 if (!e
->enumerate(e
, &gid
))
111 /* package not present in database for any product - skip */
112 if (os_type
== OS_TYPE_ANDROID
)
114 DBG2(DBG_IMV
, "package '%s' (%.*s) not found",
115 package
, version
.len
, version
.ptr
);
123 /* Convert package version chunk to a string */
124 release
= strndup(version
.ptr
, version
.len
);
126 /* Enumerate over all acceptable versions */
127 e
= this->db
->query(this->db
,
128 "SELECT release, security FROM versions "
129 "WHERE product = ? AND package = ?",
130 DB_INT
, pid
, DB_INT
, gid
, DB_TEXT
, DB_INT
);
141 while (e
->enumerate(e
, &cur_release
, &package_state
))
144 if (streq(release
, cur_release
) || streq("*", cur_release
))
156 if (package_state
== OS_PACKAGE_STATE_BLACKLIST
)
158 DBG2(DBG_IMV
, "package '%s' (%s) is blacklisted",
161 state
->add_bad_package(state
, package
, package_state
);
165 DBG2(DBG_IMV
, "package '%s' (%s)%N is ok", package
, release
,
166 os_package_state_names
, package_state
);
172 DBG1(DBG_IMV
, "package '%s' (%s) no match", package
, release
);
174 state
->add_bad_package(state
, package
, package_state
);
179 /* package not present in database for this product - skip */
185 state
->set_count(state
, count
, count_no_match
, count_blacklist
, count_ok
);
190 METHOD(imv_os_database_t
, get_device_id
, int,
191 private_imv_os_database_t
*this, chunk_t value
)
196 /* get primary key of device ID */
197 e
= this->db
->query(this->db
, "SELECT id FROM devices WHERE value = ?",
198 DB_BLOB
, value
, DB_INT
);
203 if (e
->enumerate(e
, &id
))
205 /* device ID already exists in database - return primary key */
210 /* register new device ID in database and return primary key */
211 return (this->db
->execute(this->db
, &id
,
212 "INSERT INTO devices (value) VALUES (?)", DB_BLOB
, value
) == 1) ?
216 METHOD(imv_os_database_t
, destroy
, void,
217 private_imv_os_database_t
*this)
219 this->db
->destroy(this->db
);
226 imv_os_database_t
*imv_os_database_create(char *uri
)
228 private_imv_os_database_t
*this;
232 .check_packages
= _check_packages
,
233 .get_device_id
= _get_device_id
,
236 .db
= lib
->db
->create(lib
->db
, uri
),
242 "failed to connect to OS database '%s'", uri
);
247 return &this->public;