sw-collector: Check for epoch-less Debian package versions
[strongswan.git] / src / libimcv / plugins / imc_swima / sw_collector / sw_collector_info.c
1 /*
2 * Copyright (C) 2017 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
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>.
9 *
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
13 * for more details.
14 */
15
16 #define _GNU_SOURCE
17 #include <stdio.h>
18
19 #include "sw_collector_info.h"
20
21 #include <library.h>
22 #include <utils/lexparser.h>
23
24 typedef struct private_sw_collector_info_t private_sw_collector_info_t;
25
26 /**
27 * Private data of an sw_collector_info_t object.
28 */
29 struct private_sw_collector_info_t {
30
31 /**
32 * Public members of sw_collector_info_state_t
33 */
34 sw_collector_info_t public;
35
36 /**
37 * tagCreator
38 */
39 char *tag_creator;
40
41 /**
42 * OS string 'Name_Version-Arch'
43 */
44 char *os;
45
46 /**
47 * Product string 'Name Version Arch'
48 */
49 char *product;
50
51 /**
52 * OS info about endpoint
53 */
54 imc_os_info_t *os_info;
55
56 };
57
58 /**
59 * Replaces invalid character by a valid one
60 */
61 static void sanitize_uri(char *uri, char a, char b)
62 {
63 char *pos = uri;
64
65 while (TRUE)
66 {
67 pos = strchr(pos, a);
68 if (!pos)
69 {
70 break;
71 }
72 *pos = b;
73 pos++;
74 }
75 }
76
77 METHOD(sw_collector_info_t, get_os_type, os_type_t,
78 private_sw_collector_info_t *this)
79 {
80 return this->os_info->get_type(this->os_info);
81 }
82
83 METHOD(sw_collector_info_t, get_os, char*,
84 private_sw_collector_info_t *this, char **product)
85 {
86 if (product)
87 {
88 *product = this->product;
89 }
90 return this->os;
91 }
92
93 METHOD(sw_collector_info_t, create_sw_id, char*,
94 private_sw_collector_info_t *this, char *package, char *version)
95 {
96 char *pos, *sw_id;
97 size_t len;
98
99 /* Remove architecture from package name */
100 pos = strchr(package, ':');
101 len = pos ? (pos - package) : strlen(package);
102
103 /* Build software identifier */
104 if (asprintf(&sw_id, "%s__%s-%.*s%s%s", this->tag_creator, this->os, len,
105 package, strlen(version) ? "-" : "", version) == -1)
106 {
107 return NULL;
108 }
109 sanitize_uri(sw_id, ':', '~');
110 sanitize_uri(sw_id, '+', '~');
111
112 return sw_id;
113 }
114
115 METHOD(sw_collector_info_t, destroy, void,
116 private_sw_collector_info_t *this)
117 {
118 this->os_info->destroy(this->os_info);
119 free(this->os);
120 free(this->product);
121 free(this->tag_creator);
122 free(this);
123 }
124
125 /**
126 * Described in header.
127 */
128 sw_collector_info_t *sw_collector_info_create(char *tag_creator)
129 {
130 private_sw_collector_info_t *this;
131 chunk_t os_name, os_version, os_arch;
132
133 INIT(this,
134 .public = {
135 .get_os_type = _get_os_type,
136 .get_os = _get_os,
137 .create_sw_id = _create_sw_id,
138 .destroy = _destroy,
139 },
140 .os_info = imc_os_info_create(),
141 .tag_creator = strdup(tag_creator),
142 );
143
144 os_name = this->os_info->get_name(this->os_info);
145 os_arch = this->os_info->get_version(this->os_info);
146
147 /* get_version() returns version followed by arch */
148 if (!extract_token(&os_version, ' ', &os_arch))
149 {
150 DBG1(DBG_IMC, "separation of OS version from arch failed");
151 destroy(this);
152 return NULL;
153 }
154
155 /* construct OS string */
156 if (asprintf(&this->os, "%.*s_%.*s-%.*s", os_name.len, os_name.ptr,
157 os_version.len, os_version.ptr,
158 os_arch.len, os_arch.ptr) == -1)
159 {
160 DBG1(DBG_IMC, "constructon of OS string failed");
161 destroy(this);
162 return NULL;
163 }
164
165 /* construct product string */
166 if (asprintf(&this->product, "%.*s %.*s %.*s", os_name.len, os_name.ptr,
167 os_version.len, os_version.ptr,
168 os_arch.len, os_arch.ptr) == -1)
169 {
170 DBG1(DBG_IMC, "constructon of product string failed");
171 destroy(this);
172 return NULL;
173 }
174
175 return &this->public;
176 }