Added add_segment() method to IETF attributes
[strongswan.git] / src / libimcv / imv / imv_os_info.c
1 /*
2 * Copyright (C) 2014 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 #include "imv_os_info.h"
17
18 typedef struct private_imv_os_info_t private_imv_os_info_t;
19
20 /**
21 * Private data of an imv_os_info_t object.
22 *
23 */
24 struct private_imv_os_info_t {
25
26 /**
27 * Public imv_os_info_t interface.
28 */
29 imv_os_info_t public;
30
31 /**
32 * OS type
33 */
34 os_type_t type;
35
36 /**
37 * OS name
38 */
39 chunk_t name;
40
41 /**
42 * OS version
43 */
44 chunk_t version;
45
46 /**
47 * This flag allows the OS version to be empty
48 */
49 bool version_is_set;
50
51 /**
52 * OS Product Information (OS Name | OS Version)
53 */
54 char *info;
55
56 };
57
58 METHOD(imv_os_info_t, get_type, os_type_t,
59 private_imv_os_info_t *this)
60 {
61 return this->type;
62 }
63
64 METHOD(imv_os_info_t, set_name, void,
65 private_imv_os_info_t *this, chunk_t name)
66 {
67 /* Has the OS name already been set? */
68 if (this->name.len)
69 {
70 if (chunk_equals(name, this->name))
71 {
72 return;
73 }
74 free(this->name.ptr);
75
76 /* Also clear the OS info string */
77 free(this->info);
78 this->info = NULL;
79 }
80 this->name = chunk_clone(name);
81 this->type = os_type_from_name(name);
82 }
83
84 METHOD(imv_os_info_t, get_name, chunk_t,
85 private_imv_os_info_t *this)
86 {
87 return this->name;
88 }
89
90 METHOD(imv_os_info_t, set_version, void,
91 private_imv_os_info_t *this, chunk_t version)
92 {
93 /* Has the OS version already been set? */
94 if (this->version_is_set)
95 {
96 if (chunk_equals(version, this->version))
97 {
98 return;
99 }
100 free(this->version.ptr);
101
102 /* Also clear the OS info string */
103 free(this->info);
104 this->info = NULL;
105 }
106 this->version = chunk_clone(version);
107 this->version_is_set = TRUE;
108 }
109
110 METHOD(imv_os_info_t, get_version, chunk_t,
111 private_imv_os_info_t *this)
112 {
113 return this->version;
114 }
115
116 METHOD(imv_os_info_t, get_info, char*,
117 private_imv_os_info_t *this)
118 {
119 int len;
120
121 if (!this->info)
122 {
123 /* Have both OS name and OS version been set? */
124 if (this->name.len == 0 || !this->version_is_set)
125 {
126 return NULL;
127 }
128
129 /* OS info is a concatenation of OS name and OS version */
130 len = this->name.len + 1 + this->version.len + 1;
131 this->info = malloc(len);
132 snprintf(this->info, len, "%.*s %.*s",
133 (int)this->name.len, this->name.ptr,
134 (int)this->version.len, this->version.ptr);
135 }
136 return this->info;
137 }
138
139 METHOD(imv_os_info_t, destroy, void,
140 private_imv_os_info_t *this)
141 {
142 free(this->name.ptr);
143 free(this->version.ptr);
144 free(this->info);
145 free(this);
146 }
147
148 /**
149 * See header
150 */
151 imv_os_info_t *imv_os_info_create(void)
152 {
153 private_imv_os_info_t *this;
154
155 INIT(this,
156 .public = {
157 .get_type = _get_type,
158 .set_name = _set_name,
159 .get_name = _get_name,
160 .set_version = _set_version,
161 .get_version = _get_version,
162 .get_info = _get_info,
163 .destroy = _destroy,
164 },
165 );
166
167 return &this->public;
168 }