#include <ctype.h>
#include <sys/types.h>
#include "ghasher.h"
struct faileditem{
gchar *filename;
gchar *reason;
};
static void faileditem_free_cb(gpointer data,gpointer userdata)
{
struct faileditem *item = data;
g_free(item->filename);
g_free(item->reason);
g_free(item);
}
static void read_digest_file(GHashTable * files, const char *filename, GError ** error)
{
char *line;
gsize len;
GIOChannel *f;
f = g_io_channel_new_file(filename, "r", error);
if (f == NULL) {
return;
}
/*We have the hex for the md5sum , space , then the filename*/
while (g_io_channel_read_line(f, &line, &len, NULL, error) == G_IO_STATUS_NORMAL) {
gchar *tmp, *name, *hash;
if (len == 0) {
continue;
}
tmp = line;
while (*tmp && isspace(*tmp))
++tmp;
hash = tmp;
while (*tmp && isalnum(*tmp))
++tmp;
while (*tmp && isspace(*tmp)) {
*tmp = '\0';
++tmp;
}
name = tmp;
while (*tmp) {
if (*tmp == '\n' || *tmp == '\r')
*tmp = '\0';
++tmp;
}
g_hash_table_replace(files, g_strdup(name), g_strdup(hash));
g_free(line);
}
g_io_channel_unref(f);
}
static GList *do_verify(GtkListStore *store,int hashcol,int filenamecol,GHashTable *files)
{
GtkTreeIter iter;
GList *result = NULL;
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
return NULL;
do {
gchar *h = NULL,*f = NULL,*base,*ch;
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, filenamecol, &f, -1);
if (f == NULL) {
g_print("Getting iterator failed!!\n");
continue;
}
base = g_path_get_basename(f);
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, hashcol, &h, -1);
if (h == NULL) {
struct faileditem *item;
g_print("Getting hash for %s failed!!\n",f);
item = g_new(struct faileditem,1);
item->filename = base;
item->reason = g_strdup_printf("Hash seems unavailable. This might be a bug in ghasher :-/");
result = g_list_append(result,item);
g_free(f);
continue;
}
ch = g_hash_table_lookup(files,base);
if(ch == NULL)
ch = g_hash_table_lookup(files,f);
if(ch == NULL){
struct faileditem *item;
g_print("Hash for %s does not exist!!\n",base);
item = g_new(struct faileditem,1);
item->filename = base;
item->reason = g_strdup_printf("File was not found in sum file");
result = g_list_append(result,item);
g_free(h);
continue;
}
g_free(f);
g_print("Checking '%s' '%s' == '%s' !!\n",base,h,ch);
if(g_ascii_strcasecmp(h,ch) != 0){
struct faileditem *item;
g_print("Failed '%s' '%s' != '%s' !!\n",base,h,ch);
item = g_new(struct faileditem,1);
item->filename = base;
item->reason = g_strdup_printf("Digest sum(%s) does not match sumfile(%s)",h,ch);
result = g_list_append(result,item);
g_free(h);
continue;
}
g_free(base);
g_free(h);
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
return result;
}
void verify_sumfile(GtkWidget *mainwindow,GtkListStore *filestore,int hashcol,int filecol,const char *filename)
{
GHashTable *files;
GList *failed;
GError *error = NULL;
files = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
read_digest_file(files,filename,&error);
if(error != NULL){
show_error_dialog(mainwindow,"Opening '%s' failed\n%s",filename,error->message);
g_error_free(error);
g_hash_table_destroy(files);
return;
}
failed = do_verify(filestore,hashcol,filecol,files);
if(failed != NULL)
show_error_dialog(mainwindow,"Digest does not match");
else
show_error_dialog(mainwindow,"All digest matches");
g_list_foreach(failed,faileditem_free_cb,NULL);
g_list_free(failed);
}
syntax highlighted by Code2HTML, v. 0.9.1