Annotation of embedaddon/strongswan/src/sw-collector/sw-collector.c, revision 1.1

1.1     ! misho       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: #include <string.h>
        !            19: #include <errno.h>
        !            20: #include <getopt.h>
        !            21: #include <unistd.h>
        !            22: #ifdef HAVE_SYSLOG
        !            23: # include <syslog.h>
        !            24: #endif
        !            25: 
        !            26: #include "sw_collector_db.h"
        !            27: #include "sw_collector_history.h"
        !            28: #include "sw_collector_rest_api.h"
        !            29: #include "sw_collector_dpkg.h"
        !            30: 
        !            31: #include <library.h>
        !            32: #include <utils/debug.h>
        !            33: #include <utils/lexparser.h>
        !            34: #include <collections/hashtable.h>
        !            35: 
        !            36: #include <swid_gen/swid_gen.h>
        !            37: #include <swid_gen/swid_gen_info.h>
        !            38: /**
        !            39:  * global debug output variables
        !            40:  */
        !            41: static int debug_level = 2;
        !            42: static bool stderr_quiet = FALSE;
        !            43: static int max_count = 0;
        !            44: 
        !            45: typedef enum collector_op_t collector_op_t;
        !            46: 
        !            47: enum collector_op_t {
        !            48:        COLLECTOR_OP_EXTRACT,
        !            49:        COLLECTOR_OP_LIST,
        !            50:        COLLECTOR_OP_UNREGISTERED,
        !            51:        COLLECTOR_OP_GENERATE,
        !            52:        COLLECTOR_OP_MIGRATE,
        !            53:        COLLECTOR_OP_CHECK
        !            54: };
        !            55: 
        !            56: /**
        !            57:  * sw_collector dbg function
        !            58:  */
        !            59: static void sw_collector_dbg(debug_t group, level_t level, char *fmt, ...)
        !            60: {
        !            61:        va_list args;
        !            62: 
        !            63:        if (level <= debug_level)
        !            64:        {
        !            65:                if (!stderr_quiet)
        !            66:                {
        !            67:                        va_start(args, fmt);
        !            68:                        vfprintf(stderr, fmt, args);
        !            69:                        fprintf(stderr, "\n");
        !            70:                        va_end(args);
        !            71:                }
        !            72: 
        !            73: #ifdef HAVE_SYSLOG
        !            74:                {
        !            75:                        int priority = LOG_INFO;
        !            76:                        char buffer[8192];
        !            77:                        char *current = buffer, *next;
        !            78: 
        !            79:                        /* write in memory buffer first */
        !            80:                        va_start(args, fmt);
        !            81:                        vsnprintf(buffer, sizeof(buffer), fmt, args);
        !            82:                        va_end(args);
        !            83: 
        !            84:                        /* do a syslog with every line */
        !            85:                        while (current)
        !            86:                        {
        !            87:                                next = strchr(current, '\n');
        !            88:                                if (next)
        !            89:                                {
        !            90:                                        *(next++) = '\0';
        !            91:                                }
        !            92:                                syslog(priority, "%s\n", current);
        !            93:                                current = next;
        !            94:                        }
        !            95:                }
        !            96: #endif /* HAVE_SYSLOG */
        !            97:        }
        !            98: }
        !            99: 
        !           100: /**
        !           101:  * atexit handler
        !           102:  */
        !           103: static void cleanup(void)
        !           104: {
        !           105:        library_deinit();
        !           106: #ifdef HAVE_SYSLOG
        !           107:        closelog();
        !           108: #endif
        !           109: }
        !           110: 
        !           111: /**
        !           112:  * Display usage of sw-collector command
        !           113:  */
        !           114: static void usage(void)
        !           115: {
        !           116:        printf("\
        !           117: Usage:\n\
        !           118:   sw-collector --help\n\
        !           119:   sw-collector [--debug <level>] [--quiet] [--count <event count>]\n\
        !           120:   sw-collector [--debug <level>] [--quiet] [--installed|--removed] \
        !           121: --list|-unregistered\n\
        !           122:   sw-collector [--debug <level>] [--quiet] [--installed|--removed] \
        !           123: [--full] --generate\n\
        !           124:   sw-collector [--debug <level>] [--quiet] --migrate\n\
        !           125:   sw-collector [--debug <level>] [--quiet] --check\n");
        !           126: }
        !           127: 
        !           128: /**
        !           129:  * Parse command line options
        !           130:  */
        !           131: static collector_op_t do_args(int argc, char *argv[], bool *full_tags,
        !           132:                                                          sw_collector_db_query_t *query_type)
        !           133: {
        !           134:        collector_op_t op = COLLECTOR_OP_EXTRACT;
        !           135:        bool installed = FALSE, removed = FALSE, full = FALSE;
        !           136: 
        !           137:        /* reinit getopt state */
        !           138:        optind = 0;
        !           139: 
        !           140:        while (TRUE)
        !           141:        {
        !           142:                int c;
        !           143: 
        !           144:                struct option long_opts[] = {
        !           145:                        { "help", no_argument, NULL, 'h' },
        !           146:                        { "check", no_argument, NULL, 'C' },
        !           147:                        { "count", required_argument, NULL, 'c' },
        !           148:                        { "debug", required_argument, NULL, 'd' },
        !           149:                        { "full", no_argument, NULL, 'f' },
        !           150:                        { "generate", no_argument, NULL, 'g' },
        !           151:                        { "installed", no_argument, NULL, 'i' },
        !           152:                        { "list", no_argument, NULL, 'l' },
        !           153:                        { "migrate", no_argument, NULL, 'm' },
        !           154:                        { "quiet", no_argument, NULL, 'q' },
        !           155:                        { "removed", no_argument, NULL, 'r' },
        !           156:                        { "unregistered", no_argument, NULL, 'u' },
        !           157:                        { 0,0,0,0 }
        !           158:                };
        !           159: 
        !           160:                c = getopt_long(argc, argv, "hCc:d:fgilmqru", long_opts, NULL);
        !           161:                switch (c)
        !           162:                {
        !           163:                        case EOF:
        !           164:                                break;
        !           165:                        case 'h':
        !           166:                                usage();
        !           167:                                exit(SUCCESS);
        !           168:                        case 'C':
        !           169:                                op = COLLECTOR_OP_CHECK;
        !           170:                                continue;
        !           171:                        case 'c':
        !           172:                                max_count = atoi(optarg);
        !           173:                                continue;
        !           174:                        case 'd':
        !           175:                                debug_level = atoi(optarg);
        !           176:                                continue;
        !           177:                        case 'f':
        !           178:                                full = TRUE;
        !           179:                                continue;
        !           180:                        case 'g':
        !           181:                                op = COLLECTOR_OP_GENERATE;
        !           182:                                continue;
        !           183:                        case 'i':
        !           184:                                installed = TRUE;
        !           185:                                continue;
        !           186:                        case 'l':
        !           187:                                op = COLLECTOR_OP_LIST;
        !           188:                                continue;
        !           189:                        case 'm':
        !           190:                                op = COLLECTOR_OP_MIGRATE;
        !           191:                                continue;
        !           192:                        case 'q':
        !           193:                                stderr_quiet = TRUE;
        !           194:                                continue;
        !           195:                        case 'r':
        !           196:                                removed = TRUE;
        !           197:                                continue;
        !           198:                        case 'u':
        !           199:                                op = COLLECTOR_OP_UNREGISTERED;
        !           200:                                continue;
        !           201:                        default:
        !           202:                                usage();
        !           203:                                exit(EXIT_FAILURE);
        !           204:                }
        !           205:                break;
        !           206:        }
        !           207: 
        !           208:        if ((!installed && !removed) || (installed && removed))
        !           209:        {
        !           210:                *query_type = SW_QUERY_ALL;
        !           211:        }
        !           212:        else if (installed)
        !           213:        {
        !           214:                *query_type = SW_QUERY_INSTALLED;
        !           215:        }
        !           216:        else
        !           217:        {
        !           218:                *query_type = SW_QUERY_REMOVED;
        !           219:        }
        !           220:        *full_tags = full;
        !           221: 
        !           222:        return op;
        !           223: }
        !           224: 
        !           225: /**
        !           226:  * Extract software events from apt history log files
        !           227:  */
        !           228: static int extract_history(sw_collector_db_t *db)
        !           229: {
        !           230:        sw_collector_history_t *history = NULL;
        !           231:        uint32_t epoch, last_eid, eid = 0;
        !           232:        char *history_path, *last_time = NULL, rfc_time[21];
        !           233:        chunk_t *h, history_chunk, line, cmd;
        !           234:        int status = EXIT_FAILURE;
        !           235:        bool skip = TRUE;
        !           236: 
        !           237:        /* open history file for reading */
        !           238:        history_path = lib->settings->get_str(lib->settings, "%s.history", NULL,
        !           239:                                                                                  lib->ns);
        !           240:        if (!history_path)
        !           241:        {
        !           242:                fprintf(stderr, "sw-collector.history path not set.\n");
        !           243:                return EXIT_FAILURE;
        !           244:        }
        !           245:        h = chunk_map(history_path, FALSE);
        !           246:        if (!h)
        !           247:        {
        !           248:                fprintf(stderr, "opening '%s' failed: %s", history_path,
        !           249:                                strerror(errno));
        !           250:                return EXIT_FAILURE;
        !           251:        }
        !           252:        history_chunk = *h;
        !           253: 
        !           254:        /* Instantiate history extractor */
        !           255:        history = sw_collector_history_create(db, 1);
        !           256:        if (!history)
        !           257:        {
        !           258:                chunk_unmap(h);
        !           259:                return EXIT_FAILURE;
        !           260:        }
        !           261: 
        !           262:        /* retrieve last event in database */
        !           263:        if (!db->get_last_event(db, &last_eid, &epoch, &last_time) || !last_eid)
        !           264:        {
        !           265:                goto end;
        !           266:        }
        !           267:        DBG0(DBG_IMC, "Last-Event: %s, eid = %u, epoch = %u",
        !           268:                                   last_time, last_eid, epoch);
        !           269: 
        !           270:        /* parse history file */
        !           271:        while (fetchline(&history_chunk, &line))
        !           272:        {
        !           273:                if (line.len == 0)
        !           274:                {
        !           275:                        continue;
        !           276:                }
        !           277:                if (!extract_token(&cmd, ':', &line))
        !           278:                {
        !           279:                        fprintf(stderr, "terminator symbol ':' not found.\n");
        !           280:                        goto end;
        !           281:                }
        !           282:                if (match("Start-Date", &cmd))
        !           283:                {
        !           284:                        if (!history->extract_timestamp(history, line, rfc_time))
        !           285:                        {
        !           286:                                goto end;
        !           287:                        }
        !           288: 
        !           289:                        /* have we reached new history entries? */
        !           290:                        if (skip && strcmp(rfc_time, last_time) > 0)
        !           291:                        {
        !           292:                                skip = FALSE;
        !           293:                        }
        !           294:                        if (skip)
        !           295:                        {
        !           296:                                continue;
        !           297:                        }
        !           298: 
        !           299:                        /* insert new event into database */
        !           300:                        eid = db->add_event(db, rfc_time);
        !           301:                        if (!eid)
        !           302:                        {
        !           303:                                goto end;
        !           304:                        }
        !           305:                        DBG1(DBG_IMC, "Start-Date: %s, eid = %u, epoch = %u",
        !           306:                                                   rfc_time, eid, epoch);
        !           307:                }
        !           308:                else if (skip)
        !           309:                {
        !           310:                        /* skip old history entries which have already been processed */
        !           311:                        continue;
        !           312:                }
        !           313:                else if (match("Install", &cmd))
        !           314:                {
        !           315:                        DBG1(DBG_IMC, "  Install:");
        !           316:                        if (!history->extract_packages(history, line, eid, SW_OP_INSTALL))
        !           317:                        {
        !           318:                                goto end;
        !           319:                        }
        !           320:                }
        !           321:                else if (match("Upgrade", &cmd))
        !           322:                {
        !           323:                        DBG1(DBG_IMC, "  Upgrade:");
        !           324:                        if (!history->extract_packages(history, line, eid, SW_OP_UPGRADE))
        !           325:                        {
        !           326:                                goto end;
        !           327:                        }
        !           328:                }
        !           329:                else if (match("Remove", &cmd))
        !           330:                {
        !           331:                        DBG1(DBG_IMC, "  Remove:");
        !           332:                        if (!history->extract_packages(history, line, eid, SW_OP_REMOVE))
        !           333:                        {
        !           334:                                goto end;
        !           335:                        }
        !           336:                }
        !           337:                else if (match("Purge", &cmd))
        !           338:                {
        !           339:                        DBG1(DBG_IMC, "  Purge:");
        !           340:                        if (!history->extract_packages(history, line, eid, SW_OP_REMOVE))
        !           341:                        {
        !           342:                                goto end;
        !           343:                        }
        !           344:                }
        !           345:                else if (match("End-Date", &cmd))
        !           346:                {
        !           347:                        /* Process 'max_count' events at a time */
        !           348:                        if (max_count > 0 && eid - last_eid == max_count)
        !           349:                        {
        !           350:                                fprintf(stderr, "added %d events\n", max_count);
        !           351:                                goto end;
        !           352:                        }
        !           353:                }
        !           354:        }
        !           355: 
        !           356:        if (history->merge_installed_packages(history))
        !           357:        {
        !           358:                status = EXIT_SUCCESS;
        !           359:        }
        !           360: 
        !           361: end:
        !           362:        free(last_time);
        !           363:        history->destroy(history);
        !           364:        chunk_unmap(h);
        !           365: 
        !           366:        return status;
        !           367: }
        !           368: 
        !           369: /**
        !           370:  * List all endpoint software identifiers stored in local collector database
        !           371:  */
        !           372: static int list_identifiers(sw_collector_db_t *db, sw_collector_db_query_t type)
        !           373: {
        !           374:        enumerator_t *e;
        !           375:        char *name, *package, *version;
        !           376:        uint32_t sw_id, count = 0, installed_count = 0, removed_count, installed;
        !           377: 
        !           378:        e = db->create_sw_enumerator(db, type, NULL);
        !           379:        if (!e)
        !           380:        {
        !           381:                return EXIT_FAILURE;
        !           382:        }
        !           383:        while (e->enumerate(e, &sw_id, &name, &package, &version, &installed))
        !           384:        {
        !           385:                printf("%s,%s,%s,%d\n", name, package, version, installed);
        !           386:                if (installed)
        !           387:                {
        !           388:                        installed_count++;
        !           389:                }
        !           390:                count++;
        !           391:        }
        !           392:        removed_count = count - installed_count;
        !           393:        e->destroy(e);
        !           394: 
        !           395:        switch (type)
        !           396:        {
        !           397:                case SW_QUERY_ALL:
        !           398:                        DBG1(DBG_IMC, "retrieved %u software identities with %u installed "
        !           399:                                 "and %u removed", count, installed_count, removed_count);
        !           400:                        break;
        !           401:                case SW_QUERY_INSTALLED:
        !           402:                        DBG1(DBG_IMC, "retrieved %u installed software identities", count);
        !           403:                        break;
        !           404:                case SW_QUERY_REMOVED:
        !           405:                        DBG1(DBG_IMC, "retrieved %u removed software identities", count);
        !           406:                        break;
        !           407:        }
        !           408: 
        !           409:        return EXIT_SUCCESS;
        !           410: }
        !           411: 
        !           412: static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed)
        !           413: {
        !           414:        sw_collector_db_query_t type;
        !           415:        enumerator_t *enumerator;
        !           416:        char *sw_id;
        !           417:        int count = 0;
        !           418: 
        !           419:        type = installed ? SW_QUERY_INSTALLED : SW_QUERY_REMOVED;
        !           420:        enumerator = rest_api->create_sw_enumerator(rest_api, type);
        !           421:        if (!enumerator)
        !           422:        {
        !           423:                return FALSE;
        !           424:        }
        !           425:        while (enumerator->enumerate(enumerator, &sw_id))
        !           426:        {
        !           427:                printf("%s,%s\n", sw_id, installed ? "1" : "0");
        !           428:                count++;
        !           429:        }
        !           430:        enumerator->destroy(enumerator);
        !           431:        DBG1(DBG_IMC, "%d %s software identifiers not registered", count,
        !           432:                                   installed ? "installed" : "removed");
        !           433:        return TRUE;
        !           434: }
        !           435: 
        !           436: 
        !           437: /**
        !           438:  * List all endpoint software identifiers stored in local collector database
        !           439:  * that are not registered yet in central collector database
        !           440:  */
        !           441: static int unregistered_identifiers(sw_collector_db_t *db,
        !           442:                                                                        sw_collector_db_query_t type)
        !           443: {
        !           444:        sw_collector_rest_api_t *rest_api;
        !           445:        int status = EXIT_SUCCESS;
        !           446: 
        !           447:        rest_api = sw_collector_rest_api_create(db);
        !           448:        if (!rest_api)
        !           449:        {
        !           450:                return EXIT_FAILURE;
        !           451:        }
        !           452: 
        !           453:        /* List installed software identifiers not registered centrally */
        !           454:        if (type != SW_QUERY_REMOVED && !query_registry(rest_api, TRUE))
        !           455:        {
        !           456:                status = EXIT_FAILURE;
        !           457:        }
        !           458: 
        !           459:        /* List removed software identifiers not registered centrally */
        !           460:        if (type != SW_QUERY_INSTALLED && !query_registry(rest_api, FALSE))
        !           461:        {
        !           462:                status = EXIT_FAILURE;
        !           463:        }
        !           464:        rest_api->destroy(rest_api);
        !           465: 
        !           466:        return status;
        !           467: }
        !           468: 
        !           469: /**
        !           470:  * Generate ISO 19770-2:2015 SWID tags for [installed|removed|all]
        !           471:  * SW identifiers that are not registered centrally
        !           472:  */
        !           473: static int generate_tags(sw_collector_db_t *db, bool full_tags,
        !           474:                                                 sw_collector_db_query_t type)
        !           475: {
        !           476:        swid_gen_t * swid_gen;
        !           477:        sw_collector_rest_api_t *rest_api;
        !           478:        char *name, *package, *version, *tag;
        !           479:        enumerator_t *enumerator;
        !           480:        uint32_t sw_id;
        !           481:        bool installed;
        !           482:        int count = 0, installed_count = 0, status = EXIT_FAILURE;
        !           483: 
        !           484:        swid_gen = swid_gen_create();
        !           485:        rest_api = sw_collector_rest_api_create(db);
        !           486:        if (!rest_api)
        !           487:        {
        !           488:                goto end;
        !           489:        }
        !           490: 
        !           491:        enumerator = rest_api->create_sw_enumerator(rest_api, type);
        !           492:        if (!enumerator)
        !           493:        {
        !           494:                goto end;
        !           495:        }
        !           496:        while (enumerator->enumerate(enumerator, &name))
        !           497:        {
        !           498:                sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
        !           499:                if (sw_id)
        !           500:                {
        !           501:                        tag = swid_gen->generate_tag(swid_gen, name, package, version,
        !           502:                                                                                 full_tags && installed, FALSE);
        !           503:                        if (tag)
        !           504:                        {
        !           505:                                DBG2(DBG_IMC, "  creating %s", name);
        !           506:                                printf("%s\n", tag);
        !           507:                                free(tag);
        !           508:                                count++;
        !           509:                                if (installed)
        !           510:                                {
        !           511:                                        installed_count++;
        !           512:                                }
        !           513:                        }
        !           514:                        free(package);
        !           515:                        free(version);
        !           516:                }
        !           517:        }
        !           518:        enumerator->destroy(enumerator);
        !           519:        status = EXIT_SUCCESS;
        !           520: 
        !           521:        switch (type)
        !           522:        {
        !           523:                case SW_QUERY_ALL:
        !           524:                        DBG1(DBG_IMC, "created %d tags for unregistered software "
        !           525:                                 "identifiers with %d installed and %d removed", count,
        !           526:                                 installed_count,  count - installed_count);
        !           527:                        break;
        !           528:                case SW_QUERY_INSTALLED:
        !           529:                        DBG1(DBG_IMC, "created %d tags for unregistered installed software "
        !           530:                                 "identifiers", count);
        !           531:                        break;
        !           532:                case SW_QUERY_REMOVED:
        !           533:                        DBG1(DBG_IMC, "created %d tags for unregistered removed software "
        !           534:                                 "identifiers", count);
        !           535:                        break;
        !           536:        }
        !           537: 
        !           538: end:
        !           539:        swid_gen->destroy(swid_gen);
        !           540:        DESTROY_IF(rest_api);
        !           541: 
        !           542:        return status;
        !           543: }
        !           544: 
        !           545: /**
        !           546:  * Remove architecture suffix from package entries in the database
        !           547:  */
        !           548: static int migrate(sw_collector_db_t *db)
        !           549: {
        !           550:        sw_collector_dpkg_t *dpkg;
        !           551: 
        !           552:        char *package, *arch, *version;
        !           553:        char package_filter[BUF_LEN];
        !           554:        int res, count = 0;
        !           555:        int status = EXIT_SUCCESS;
        !           556:        enumerator_t *enumerator;
        !           557: 
        !           558:        dpkg = sw_collector_dpkg_create();
        !           559:        if (!dpkg)
        !           560:        {
        !           561:                return FAILED;
        !           562:        }
        !           563: 
        !           564:        enumerator = dpkg->create_sw_enumerator(dpkg);
        !           565:        while (enumerator->enumerate(enumerator, &package, &arch, &version))
        !           566:        {
        !           567: 
        !           568:                /* Look for package names with architecture suffix */
        !           569:                snprintf(package_filter, BUF_LEN, "%s:%%", package);
        !           570: 
        !           571:                res = db->update_package(db, package_filter, package);
        !           572:                if (res < 0)
        !           573:                {
        !           574:                                status = EXIT_FAILURE;
        !           575:                                break;
        !           576:                }
        !           577:                else if (res > 0)
        !           578:                {
        !           579:                        count += res;
        !           580:                        DBG2(DBG_IMC, "%s: removed arch suffix %d times", package, res);
        !           581:                }
        !           582:        }
        !           583:        enumerator->destroy(enumerator);
        !           584:        dpkg->destroy(dpkg);
        !           585: 
        !           586:        DBG1(DBG_IMC, "migrated %d sw identifier records", count);
        !           587: 
        !           588:        return status;
        !           589: }
        !           590: 
        !           591: /**
        !           592:  * Free hashtable entry
        !           593:  */
        !           594: static void free_entry(void *value, void *key)
        !           595: {
        !           596:        free(value);
        !           597:        free(key);
        !           598: }
        !           599: 
        !           600: /**
        !           601:  * Check consistency of installed software identifiers in collector database
        !           602:  */
        !           603: static int check(sw_collector_db_t *db)
        !           604: {
        !           605:        sw_collector_dpkg_t *dpkg;
        !           606:        swid_gen_info_t *info;
        !           607:        hashtable_t *table;
        !           608:        enumerator_t *e;
        !           609:        char *dpkg_name, *name, *package, *arch, *version;
        !           610:        uint32_t sw_id, count = 0, installed;
        !           611: 
        !           612:        dpkg = sw_collector_dpkg_create();
        !           613:        if (!dpkg)
        !           614:        {
        !           615:                return EXIT_FAILURE;
        !           616:        }
        !           617:        info = swid_gen_info_create();
        !           618:        table = hashtable_create(hashtable_hash_str, hashtable_equals_str, 4096);
        !           619: 
        !           620:        /* Store all installed sw identifiers (according to dpkg) in hashtable */
        !           621:        e = dpkg->create_sw_enumerator(dpkg);
        !           622:        while (e->enumerate(e, &package, &arch, &version))
        !           623:        {
        !           624:                dpkg_name = info->create_sw_id(info, package, version);
        !           625:                table->put(table, strdup(package), dpkg_name);
        !           626:        }
        !           627:        e->destroy(e);
        !           628: 
        !           629:        info->destroy(info);
        !           630:        dpkg->destroy(dpkg);
        !           631: 
        !           632:        e = db->create_sw_enumerator(db, SW_QUERY_ALL, NULL);
        !           633:        if (!e)
        !           634:        {
        !           635:                table->destroy_function(table, (void*)free_entry);
        !           636:                return EXIT_FAILURE;
        !           637:        }
        !           638:        while (e->enumerate(e, &sw_id, &name, &package, &version, &installed))
        !           639:        {
        !           640:                dpkg_name = table->get(table, package);
        !           641:                if (installed)
        !           642:                {
        !           643:                        if (!dpkg_name)
        !           644:                        {
        !           645:                                printf("%4d %s erroneously noted as installed\n", sw_id, name);
        !           646:                        }
        !           647:                        else if (!streq(name, dpkg_name))
        !           648:                        {
        !           649:                                printf("%4d %s erroneously noted as installed instead of\n "
        !           650:                                           "    %s\n", sw_id, name, dpkg_name);
        !           651:                        }
        !           652:                }
        !           653:                else
        !           654:                {
        !           655:                        if (dpkg_name && streq(name, dpkg_name))
        !           656:                        {
        !           657:                                printf("%4d %s erroneously noted as removed\n", sw_id, name);
        !           658:                        }
        !           659:                }
        !           660:                count++;
        !           661:        }
        !           662:        e->destroy(e);
        !           663: 
        !           664:        table->destroy_function(table, (void*)free_entry);
        !           665:        printf("checked %d software identifiers\n", count);
        !           666: 
        !           667:        return EXIT_SUCCESS;
        !           668: }
        !           669: 
        !           670: int main(int argc, char *argv[])
        !           671: {
        !           672:        sw_collector_db_t *db = NULL;
        !           673:        sw_collector_db_query_t query_type;
        !           674:        collector_op_t op;
        !           675:        bool full_tags;
        !           676:        char *uri;
        !           677:        int status = EXIT_FAILURE;
        !           678: 
        !           679:        op = do_args(argc, argv, &full_tags, &query_type);
        !           680: 
        !           681:        /* enable sw_collector debugging hook */
        !           682:        dbg = sw_collector_dbg;
        !           683: #ifdef HAVE_SYSLOG
        !           684:        openlog("sw-collector", 0, LOG_DEBUG);
        !           685: #endif
        !           686: 
        !           687:        atexit(cleanup);
        !           688: 
        !           689:        /* initialize library */
        !           690:        if (!library_init(NULL, "sw-collector"))
        !           691:        {
        !           692:                exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
        !           693:        }
        !           694: 
        !           695:        /* load sw-collector plugins */
        !           696:        if (!lib->plugins->load(lib->plugins,
        !           697:                        lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
        !           698:        {
        !           699:                exit(SS_RC_INITIALIZATION_FAILED);
        !           700:        }
        !           701: 
        !           702:        /* connect to sw-collector database */
        !           703:        uri = lib->settings->get_str(lib->settings, "%s.database", NULL, lib->ns);
        !           704:        if (!uri)
        !           705:        {
        !           706:                fprintf(stderr, "sw-collector.database URI not set.\n");
        !           707:                exit(EXIT_FAILURE);
        !           708:        }
        !           709:        db = sw_collector_db_create(uri);
        !           710:        if (!db)
        !           711:        {
        !           712:                fprintf(stderr, "connection to sw-collector database failed.\n");
        !           713:                exit(EXIT_FAILURE);
        !           714:        }
        !           715: 
        !           716:        switch (op)
        !           717:        {
        !           718:                case COLLECTOR_OP_EXTRACT:
        !           719:                        status = extract_history(db);
        !           720:                        break;
        !           721:                case COLLECTOR_OP_LIST:
        !           722:                        status = list_identifiers(db, query_type);
        !           723:                        break;
        !           724:                case COLLECTOR_OP_UNREGISTERED:
        !           725:                        status = unregistered_identifiers(db, query_type);
        !           726:                        break;
        !           727:                case COLLECTOR_OP_GENERATE:
        !           728:                        status = generate_tags(db, full_tags, query_type);
        !           729:                        break;
        !           730:                case COLLECTOR_OP_MIGRATE:
        !           731:                        status = migrate(db);
        !           732:                        break;
        !           733:                case COLLECTOR_OP_CHECK:
        !           734:                        status = check(db);
        !           735:                        break;
        !           736:        }
        !           737:        db->destroy(db);
        !           738: 
        !           739:        exit(status);
        !           740: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>