Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

294 lines (268 sloc) 8.621 kB
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2013 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdlib.h>
#include <colord.h>
#include <locale.h>
typedef struct {
GHashTable *cmfbinary;
GHashTable *vendors;
GHashTable *vendors_broken;
GHashTable *vendors_no_serial;
GString *csv_all;
GString *csv_fail;
guint has_serial_numbers;
} CdFindBrokenPriv;
/**
* cd_find_broken_parse_filename:
*/
static gboolean
cd_find_broken_parse_filename (CdFindBrokenPriv *priv,
const gchar *filename,
GError **error)
{
CdIcc *icc = NULL;
CdProfileWarning warning;
const gchar *tmp;
GArray *warnings = NULL;
gboolean ret;
gchar *vendor = NULL;
GFile *file = NULL;
guint i;
guint *val;
/* load file */
icc = cd_icc_new ();
file = g_file_new_for_path (filename);
ret = cd_icc_load_file (icc,
file,
CD_ICC_LOAD_FLAGS_METADATA | CD_ICC_LOAD_FLAGS_PRIMARIES,
NULL,
error);
if (!ret)
goto out;
/* append to CSV file */
g_string_append_printf (priv->csv_all, "%s,\"%s\",\"%s\",%s,%s,%.1f,%s,%s\n",
cd_icc_get_filename (icc),
cd_icc_get_manufacturer (icc, NULL, NULL),
cd_icc_get_model (icc, NULL, NULL),
cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_DATA_SOURCE),
cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_EDID_SERIAL),
cd_icc_get_version (icc),
cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_CMF_BINARY),
cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_CMF_VERSION));
/* get quirked vendor */
tmp = cd_icc_get_manufacturer (icc, NULL, NULL);
if (tmp == NULL)
vendor = g_strdup ("Unknown");
else
vendor = cd_quirk_vendor_name (tmp);
val = g_hash_table_lookup (priv->vendors, vendor);
if (val == NULL) {
val = g_new0 (guint, 1);
g_hash_table_insert (priv->vendors, g_strdup (vendor), val);
}
(*val)++;
/* count those with serial numbers */
tmp = cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_EDID_SERIAL);
if (tmp != NULL && tmp[0] != '\0') {
priv->has_serial_numbers++;
} else {
val = g_hash_table_lookup (priv->vendors_no_serial, vendor);
if (val == NULL) {
val = g_new0 (guint, 1);
g_hash_table_insert (priv->vendors_no_serial, g_strdup (vendor), val);
}
(*val)++;
}
/* get CMF binary */
tmp = cd_icc_get_metadata_item (icc, CD_PROFILE_METADATA_CMF_BINARY);
if (tmp == NULL)
tmp = "Unknown";
val = g_hash_table_lookup (priv->cmfbinary, tmp);
if (val == NULL) {
val = g_new0 (guint, 1);
g_hash_table_insert (priv->cmfbinary, g_strdup (tmp), val);
}
(*val)++;
/* any problems */
warnings = cd_icc_get_warnings (icc);
if (warnings->len == 0)
goto out;
/* count those with problems */
val = g_hash_table_lookup (priv->vendors_broken, vendor);
if (val == NULL) {
val = g_new0 (guint, 1);
g_hash_table_insert (priv->vendors_broken, g_strdup (vendor), val);
}
(*val)++;
/* append to CSV file */
g_string_append_printf (priv->csv_fail, "%s,\"%s\",\"%s\",",
cd_icc_get_filename (icc),
cd_icc_get_manufacturer (icc, NULL, NULL),
cd_icc_get_model (icc, NULL, NULL));
for (i = 0; i < warnings->len; i++) {
warning = g_array_index (warnings, CdProfileWarning, i);
g_string_append_printf (priv->csv_fail, "%s|",
cd_profile_warning_to_string (warning));
}
priv->csv_fail->str[priv->csv_fail->len - 1] = '\n';
out:
if (warnings != NULL)
g_array_unref (warnings);
g_object_unref (file);
g_object_unref (icc);
g_free (vendor);
return ret;
}
/**
* cd_find_broken_strcmp_func:
*/
static gint
cd_find_broken_strcmp_func (gconstpointer a, gconstpointer b)
{
return g_strcmp0 ((const gchar *) a, (const gchar *) b);
}
/**
* main:
*/
int
main (int argc, char *argv[])
{
CdFindBrokenPriv *priv = NULL;
const gchar *fn_all = "./all.csv";
const gchar *fn_failures = "./results.csv";
gboolean ret;
GError *error = NULL;
gint retval = EXIT_FAILURE;
GList *l;
GList *list;
guint i;
guint total = 0;
guint total_with_warnings = 0;
guint *val;
if (argc < 2) {
g_warning ("usage: cd-find-broken.c filename, e.g. 'uploads/*'");
goto out;
}
setlocale (LC_ALL, "");
/* create CSV headers */
priv = g_new0 (CdFindBrokenPriv, 1);
priv->csv_all = g_string_new ("filename,vendor,model,serial,data_source,version,cmf_binary,cmf_version\n");
priv->csv_fail = g_string_new ("filename,vendor,model,warnings\n");
priv->vendors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->vendors_no_serial = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->vendors_broken = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->cmfbinary = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->has_serial_numbers = 0;
/* scan each file */
for (i = 1; i < (guint) argc; i++) {
ret = cd_find_broken_parse_filename (priv, argv[i], &error);
if (!ret) {
g_warning ("failed to parse %s: %s",
argv[i], error->message);
g_clear_error (&error);
}
}
/* print stats */
total = argc - 1;
for (i = 0; i < priv->csv_fail->len; i++) {
if (priv->csv_fail->str[i] == '\n')
total_with_warnings++;
}
total_with_warnings--;
g_print ("Total profiles scanned: %i\n", total);
g_print ("Profiles with invalid or unlikely primaries: %i [%.1f%%]\n",
total_with_warnings,
(gdouble) 100.0f * total_with_warnings / total);
g_print ("Profiles with valid serial numbers: %i [%.1f%%]\n",
priv->has_serial_numbers,
(gdouble) 100.0f * priv->has_serial_numbers / total);
/* extract vendors */
if (FALSE) {
list = g_hash_table_get_keys (priv->vendors);
list = g_list_sort (list, cd_find_broken_strcmp_func);
g_print ("Vendor list:\n");
for (l = list; l != NULL; l = l->next) {
val = (guint *) g_hash_table_lookup (priv->vendors, l->data);
g_print ("\"%s\",%i\n", (const gchar *) l->data, *val);
}
g_list_free (list);
}
/* extract vendors that ship broken primaries */
if (FALSE) {
list = g_hash_table_get_keys (priv->vendors_broken);
list = g_list_sort (list, cd_find_broken_strcmp_func);
g_print ("Vendors who ship broken primaries:\n");
for (l = list; l != NULL; l = l->next) {
val = (guint *) g_hash_table_lookup (priv->vendors_broken, l->data);
g_print ("\"%s\",%i\n", (const gchar *) l->data, *val);
}
g_list_free (list);
}
/* extract vendors without serial numbers */
if (FALSE) {
list = g_hash_table_get_keys (priv->vendors_no_serial);
list = g_list_sort (list, cd_find_broken_strcmp_func);
g_print ("Vendors who don't write serial numbers:\n");
for (l = list; l != NULL; l = l->next) {
val = (guint *) g_hash_table_lookup (priv->vendors_no_serial, l->data);
g_print ("\"%s\",%i\n", (const gchar *) l->data, *val);
}
g_list_free (list);
}
/* extract cmfbinary */
if (FALSE) {
list = g_hash_table_get_keys (priv->cmfbinary);
g_print ("CMF list:\n");
for (l = list; l != NULL; l = l->next) {
val = (guint *) g_hash_table_lookup (priv->cmfbinary, l->data);
g_print ("\"%s\",%i\n", (const gchar *) l->data, *val);
}
g_list_free (list);
}
/* save the files */
ret = g_file_set_contents (fn_all, priv->csv_all->str, -1, &error);
if (!ret) {
g_warning ("%s", error->message);
g_error_free (error);
goto out;
}
ret = g_file_set_contents (fn_failures, priv->csv_fail->str, -1, &error);
if (!ret) {
g_warning ("%s", error->message);
g_error_free (error);
goto out;
}
/* success */
g_print ("Written to %s and %s\n", fn_failures, fn_all);
retval = EXIT_SUCCESS;
out:
if (priv != NULL) {
g_hash_table_unref (priv->cmfbinary);
g_hash_table_unref (priv->vendors);
g_hash_table_unref (priv->vendors_no_serial);
g_hash_table_unref (priv->vendors_broken);
g_string_free (priv->csv_all, TRUE);
g_string_free (priv->csv_fail, TRUE);
}
g_free (priv);
return retval;
}
Jump to Line
Something went wrong with that request. Please try again.