trap-manager: Wait for install to finish before uninstalling
[strongswan.git] / src / sw-collector / sw_collector_dpkg.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_dpkg.h"
20
21 typedef struct private_sw_collector_dpkg_t private_sw_collector_dpkg_t;
22
23 /**
24 * Private data of an sw_collector_dpkg_t object.
25 */
26 struct private_sw_collector_dpkg_t {
27
28 /**
29 * Public members of sw_collector_dpkg_state_t
30 */
31 sw_collector_dpkg_t public;
32
33 };
34
35 typedef struct {
36 /** public enumerator interface */
37 enumerator_t public;
38 /** dpkg output stream */
39 FILE *file;
40 /** current dpkg output line */
41 char line[BUF_LEN];
42 } dpkg_enumerator_t;
43
44 METHOD(enumerator_t, enumerate, bool,
45 dpkg_enumerator_t *this, va_list args)
46 {
47 char **package, **arch, **version, *state, *pos;
48
49 VA_ARGS_VGET(args, package, arch, version);
50
51 while (TRUE)
52 {
53 if (!fgets(this->line, BUF_LEN, this->file))
54 {
55 return FALSE;
56 }
57
58 *package = this->line;
59 pos = strchr(this->line, '\t');
60 if (!pos)
61 {
62 return FALSE;
63 }
64 *pos = '\0';
65
66 *arch = ++pos;
67 pos = strchr(pos, '\t');
68 if (!pos)
69 {
70 return FALSE;
71 }
72 *pos = '\0';
73
74 *version = ++pos;
75 pos = strchr(pos, '\t');
76 if (!pos)
77 {
78 return FALSE;
79 }
80 *pos = '\0';
81
82 state = ++pos;
83 pos = strchr(pos, '\n');
84 if (!pos)
85 {
86 return FALSE;
87 }
88 *pos = '\0';
89
90 if (streq(state, "install ok installed"))
91 {
92 return TRUE;
93 }
94 }
95 }
96
97 METHOD(enumerator_t, enumerator_destroy, void,
98 dpkg_enumerator_t *this)
99 {
100 pclose(this->file);
101 free(this);
102 }
103
104 METHOD(sw_collector_dpkg_t, create_sw_enumerator, enumerator_t*,
105 private_sw_collector_dpkg_t *this)
106 {
107 dpkg_enumerator_t *enumerator;
108 char cmd[] = "dpkg-query -W -f="
109 "\'${Package}\t${Architecture}\t${Version}\t${Status}\n\'";
110 FILE *file;
111
112 file = popen(cmd, "r");
113 if (!file)
114 {
115 DBG1(DBG_IMC, "failed to run dpgk-query command");
116 return NULL;
117 }
118
119 INIT(enumerator,
120 .public = {
121 .enumerate = enumerator_enumerate_default,
122 .venumerate = _enumerate,
123 .destroy = _enumerator_destroy,
124 },
125 .file = file,
126 );
127
128 return &enumerator->public;
129 }
130
131 METHOD(sw_collector_dpkg_t, destroy, void,
132 private_sw_collector_dpkg_t *this)
133 {
134 free(this);
135 }
136
137 /**
138 * Described in header.
139 */
140 sw_collector_dpkg_t *sw_collector_dpkg_create(void)
141 {
142 private_sw_collector_dpkg_t *this;
143
144 INIT(this,
145 .public = {
146 .create_sw_enumerator = _create_sw_enumerator,
147 .destroy = _destroy,
148 },
149 );
150
151 return &this->public;
152 }