153 lines
2.9 KiB
C
153 lines
2.9 KiB
C
/*
|
|
* Copyright (C) 2017 Andreas Steffen
|
|
* HSR Hochschule fuer Technik Rapperswil
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include <stdio.h>
|
|
|
|
#include "sw_collector_dpkg.h"
|
|
|
|
typedef struct private_sw_collector_dpkg_t private_sw_collector_dpkg_t;
|
|
|
|
/**
|
|
* Private data of an sw_collector_dpkg_t object.
|
|
*/
|
|
struct private_sw_collector_dpkg_t {
|
|
|
|
/**
|
|
* Public members of sw_collector_dpkg_state_t
|
|
*/
|
|
sw_collector_dpkg_t public;
|
|
|
|
};
|
|
|
|
typedef struct {
|
|
/** public enumerator interface */
|
|
enumerator_t public;
|
|
/** dpkg output stream */
|
|
FILE *file;
|
|
/** current dpkg output line */
|
|
char line[BUF_LEN];
|
|
} dpkg_enumerator_t;
|
|
|
|
METHOD(enumerator_t, enumerate, bool,
|
|
dpkg_enumerator_t *this, va_list args)
|
|
{
|
|
char **package, **arch, **version, *state, *pos;
|
|
|
|
VA_ARGS_VGET(args, package, arch, version);
|
|
|
|
while (TRUE)
|
|
{
|
|
if (!fgets(this->line, BUF_LEN, this->file))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
*package = this->line;
|
|
pos = strchr(this->line, '\t');
|
|
if (!pos)
|
|
{
|
|
return FALSE;
|
|
}
|
|
*pos = '\0';
|
|
|
|
*arch = ++pos;
|
|
pos = strchr(pos, '\t');
|
|
if (!pos)
|
|
{
|
|
return FALSE;
|
|
}
|
|
*pos = '\0';
|
|
|
|
*version = ++pos;
|
|
pos = strchr(pos, '\t');
|
|
if (!pos)
|
|
{
|
|
return FALSE;
|
|
}
|
|
*pos = '\0';
|
|
|
|
state = ++pos;
|
|
pos = strchr(pos, '\n');
|
|
if (!pos)
|
|
{
|
|
return FALSE;
|
|
}
|
|
*pos = '\0';
|
|
|
|
if (streq(state, "install ok installed"))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
METHOD(enumerator_t, enumerator_destroy, void,
|
|
dpkg_enumerator_t *this)
|
|
{
|
|
pclose(this->file);
|
|
free(this);
|
|
}
|
|
|
|
METHOD(sw_collector_dpkg_t, create_sw_enumerator, enumerator_t*,
|
|
private_sw_collector_dpkg_t *this)
|
|
{
|
|
dpkg_enumerator_t *enumerator;
|
|
char cmd[] = "dpkg-query -W -f="
|
|
"\'${Package}\t${Architecture}\t${Version}\t${Status}\n\'";
|
|
FILE *file;
|
|
|
|
file = popen(cmd, "r");
|
|
if (!file)
|
|
{
|
|
DBG1(DBG_IMC, "failed to run dpgk-query command");
|
|
return NULL;
|
|
}
|
|
|
|
INIT(enumerator,
|
|
.public = {
|
|
.enumerate = enumerator_enumerate_default,
|
|
.venumerate = _enumerate,
|
|
.destroy = _enumerator_destroy,
|
|
},
|
|
.file = file,
|
|
);
|
|
|
|
return &enumerator->public;
|
|
}
|
|
|
|
METHOD(sw_collector_dpkg_t, destroy, void,
|
|
private_sw_collector_dpkg_t *this)
|
|
{
|
|
free(this);
|
|
}
|
|
|
|
/**
|
|
* Described in header.
|
|
*/
|
|
sw_collector_dpkg_t *sw_collector_dpkg_create(void)
|
|
{
|
|
private_sw_collector_dpkg_t *this;
|
|
|
|
INIT(this,
|
|
.public = {
|
|
.create_sw_enumerator = _create_sw_enumerator,
|
|
.destroy = _destroy,
|
|
},
|
|
);
|
|
|
|
return &this->public;
|
|
}
|