12bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen/* -*- mode: C; c-file-style: "gnu" -*- */ 22bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen/* xdgmimeicon.c: Private file. Datastructure for storing the aliases. 32bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 42bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * More info can be found at http://www.freedesktop.org/standards/ 52bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 62bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Copyright (C) 2008 Red Hat, Inc. 72bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 82bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Licensed under the Academic Free License version 2.0 92bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Or under the following terms: 102bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 112bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * This library is free software; you can redistribute it and/or 122bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * modify it under the terms of the GNU Lesser General Public 132bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * License as published by the Free Software Foundation; either 142bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * version 2 of the License, or (at your option) any later version. 152bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 162bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * This library is distributed in the hope that it will be useful, 172bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * but WITHOUT ANY WARRANTY; without even the implied warranty of 182bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 192bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Lesser General Public License for more details. 202bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * 212bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * You should have received a copy of the GNU Lesser General Public 222bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * License along with this library; if not, write to the 232bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 242bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Boston, MA 02111-1307, USA. 252bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen */ 262bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 272bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#ifdef HAVE_CONFIG_H 28761424465aaad736916b029383483b6ac419d831Johan Dahlin#include "config.h" 292bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#endif 302bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 312bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include "xdgmimeicon.h" 322bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include "xdgmimeint.h" 332bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include <stdlib.h> 342bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include <stdio.h> 352bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include <assert.h> 362bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include <string.h> 372bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#include <fnmatch.h> 382bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 392bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#ifndef FALSE 402bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#define FALSE (0) 412bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#endif 422bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 432bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#ifndef TRUE 442bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#define TRUE (!FALSE) 452bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen#endif 462bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 472bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasentypedef struct XdgIcon XdgIcon; 482bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 492bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenstruct XdgIcon 502bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 512bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen char *mime_type; 522bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen char *icon_name; 532bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen}; 542bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 552bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenstruct XdgIconList 562bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 572bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen struct XdgIcon *icons; 582bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen int n_icons; 592bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen}; 602bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 612bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias ClasenXdgIconList * 622bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen_xdg_mime_icon_list_new (void) 632bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 642bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen XdgIconList *list; 652bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 662bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list = malloc (sizeof (XdgIconList)); 672bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 682bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons = NULL; 692bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->n_icons = 0; 702bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 712bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen return list; 722bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 732bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 742bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenvoid 752bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen_xdg_mime_icon_list_free (XdgIconList *list) 762bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 772bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen int i; 782bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 792bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (list->icons) 802bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 812bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen for (i = 0; i < list->n_icons; i++) 822bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 832bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen free (list->icons[i].mime_type); 842bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen free (list->icons[i].icon_name); 852bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 862bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen free (list->icons); 872bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 882bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen free (list); 892bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 902bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 912bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenstatic int 922bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenicon_entry_cmp (const void *v1, const void *v2) 932bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 942bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen return strcmp (((XdgIcon *)v1)->mime_type, ((XdgIcon *)v2)->mime_type); 952bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 962bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 972bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenconst char * 982bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen_xdg_mime_icon_list_lookup (XdgIconList *list, 992bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen const char *mime_type) 1002bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 1012bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen XdgIcon *entry; 1022bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen XdgIcon key; 1032bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1042bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (list->n_icons > 0) 1052bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 1062bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen key.mime_type = (char *)mime_type; 1072bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen key.icon_name = NULL; 1082bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1092bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen entry = bsearch (&key, list->icons, list->n_icons, 1102bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen sizeof (XdgIcon), icon_entry_cmp); 1112bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (entry) 1122bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen return entry->icon_name; 1132bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 1142bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1152bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen return NULL; 1162bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 1172bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1182bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenvoid 1192bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen_xdg_mime_icon_read_from_file (XdgIconList *list, 1202bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen const char *file_name) 1212bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 1222bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen FILE *file; 1232bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen char line[255]; 1242bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen int alloc; 1252bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1262bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen file = fopen (file_name, "r"); 1272bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1282bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (file == NULL) 1292bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen return; 1302bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1312bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. 1322bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen * Blah */ 1332bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen alloc = list->n_icons + 16; 1342bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons = realloc (list->icons, alloc * sizeof (XdgIcon)); 1352bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen while (fgets (line, 255, file) != NULL) 1362bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 1372bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen char *sep; 1382bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (line[0] == '#') 1392bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen continue; 1402bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1412bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen sep = strchr (line, ':'); 1422bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (sep == NULL) 1432bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen continue; 1442bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen *(sep++) = '\000'; 1452bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen sep[strlen (sep) -1] = '\000'; 1462bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (list->n_icons == alloc) 1472bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 1482bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen alloc <<= 1; 1492bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons = realloc (list->icons, 1502bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen alloc * sizeof (XdgIcon)); 1512bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 1522bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons[list->n_icons].mime_type = strdup (line); 1532bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons[list->n_icons].icon_name = strdup (sep); 1542bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->n_icons++; 1552bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 1562bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons = realloc (list->icons, 1572bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->n_icons * sizeof (XdgIcon)); 1582bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1592bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen fclose (file); 1602bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1612bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (list->n_icons > 1) 1622bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen qsort (list->icons, list->n_icons, 1632bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen sizeof (XdgIcon), icon_entry_cmp); 1642bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 1652bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1662bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1672bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasenvoid 1682bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen_xdg_mime_icon_list_dump (XdgIconList *list) 1692bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen{ 1702bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen int i; 1712bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1722bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen if (list->icons) 1732bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 1742bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen for (i = 0; i < list->n_icons; i++) 1752bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen { 1762bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen printf ("%s %s\n", 1772bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons[i].mime_type, 1782bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen list->icons[i].icon_name); 1792bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 1802bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen } 1812bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen} 1822bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 1832bd31c9e6c6159a5ef0a92ea567b48649256ab43Matthias Clasen 184