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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>