#include #include #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); }