2 * The PCI Library -- ID to Name Cache
4 * Copyright (c) 2008 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
13 #include <sys/types.h>
22 static const char cache_version[] = "#PCI-CACHE-1.0";
25 pci_id_cache_load(struct pci_access *a, int flags)
29 const char default_name[] = "/.pciids-cache";
33 a->id_cache_status = 1;
34 if (!a->id_cache_file)
36 /* Construct the default ID cache name */
38 struct passwd *pw = getpwuid(uid);
41 name = pci_malloc(a, strlen(pw->pw_dir) + sizeof(default_name));
42 sprintf(name, "%s%s", pw->pw_dir, default_name);
43 pci_set_id_cache(a, name, 1);
45 a->debug("Using cache %s\n", a->id_cache_file);
46 if (flags & PCI_LOOKUP_REFRESH_CACHE)
48 a->debug("Not loading cache, will refresh everything\n");
49 a->id_cache_status = 2;
53 f = fopen(a->id_cache_file, "rb");
56 a->debug("Cache file does not exist\n");
59 /* FIXME: Compare timestamp with the pci.ids file? */
62 while (fgets(line, sizeof(line), f))
64 char *p = strchr(line, '\n');
71 if (strcmp(line, cache_version))
73 a->debug("Unrecognized cache version %s, ignoring\n", line);
80 int cat, id1, id2, id3, id4, cnt;
81 if (sscanf(line, "%d%x%x%x%x%n", &cat, &id1, &id2, &id3, &id4, &cnt) >= 5)
84 while (*p && *p == ' ')
86 pci_id_insert(a, cat, id1, id2, id3, id4, p, SRC_CACHE);
91 a->warning("Malformed cache file %s (line %d), ignoring", a->id_cache_file, lino);
96 a->warning("Error while reading %s", a->id_cache_file);
102 pci_id_cache_flush(struct pci_access *a)
104 int orig_status = a->id_cache_status;
107 struct id_entry *e, *e2;
109 a->id_cache_status = 0;
112 if (!a->id_cache_file)
114 f = fopen(a->id_cache_file, "wb");
117 a->warning("Cannot write %s: %s", a->id_cache_file, strerror(errno));
120 a->debug("Writing cache to %s\n", a->id_cache_file);
121 fprintf(f, "%s\n", cache_version);
123 for (h=0; h<HASH_SIZE; h++)
124 for (e=a->id_hash[h]; e; e=e->next)
125 if (e->src == SRC_CACHE || e->src == SRC_NET)
127 /* Verify that every entry is written at most once */
128 for (e2=a->id_hash[h]; e2 != e; e2=e2->next)
129 if ((e2->src == SRC_CACHE || e2->src == SRC_NET) &&
131 e2->id12 == e->id12 && e2->id34 == e->id34)
134 fprintf(f, "%d %x %x %x %x %s\n",
136 pair_first(e->id12), pair_second(e->id12),
137 pair_first(e->id34), pair_second(e->id34),
143 a->warning("Error writing %s", a->id_cache_file);
149 int pci_id_cache_load(struct pci_access *a UNUSED, int flags UNUSED)
151 a->id_cache_status = 1;
155 void pci_id_cache_flush(struct pci_access *a)
157 a->id_cache_status = 0;
163 pci_id_cache_dirty(struct pci_access *a)
165 if (a->id_cache_status >= 1)
166 a->id_cache_status = 2;
170 pci_set_id_cache(struct pci_access *a, char *name, int to_be_freed)
172 if (a->free_id_cache_file)
173 free(a->id_cache_file);
174 a->id_cache_file = name;
175 a->free_id_cache_file = to_be_freed;