]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names-cache.c
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";
24 static char *get_cache_name(struct pci_access
*a
)
28 name
= pci_get_param(a
, "net.cache_name");
29 if (!name
|| !name
[0])
31 if (strncmp(name
, "~/", 2))
35 struct passwd
*pw
= getpwuid(uid
);
39 buf
= pci_malloc(a
, strlen(pw
->pw_dir
) + strlen(name
+1) + 1);
40 sprintf(buf
, "%s%s", pw
->pw_dir
, name
+1);
41 pci_set_param_internal(a
, "net.cache_name", buf
, 0);
46 pci_id_cache_load(struct pci_access
*a
, int flags
)
53 a
->id_cache_status
= 1;
54 name
= get_cache_name(a
);
57 a
->debug("Using cache %s\n", name
);
58 if (flags
& PCI_LOOKUP_REFRESH_CACHE
)
60 a
->debug("Not loading cache, will refresh everything\n");
61 a
->id_cache_status
= 2;
65 f
= fopen(name
, "rb");
68 a
->debug("Cache file does not exist\n");
71 /* FIXME: Compare timestamp with the pci.ids file? */
74 while (fgets(line
, sizeof(line
), f
))
76 char *p
= strchr(line
, '\n');
83 if (strcmp(line
, cache_version
))
85 a
->debug("Unrecognized cache version %s, ignoring\n", line
);
92 int cat
, id1
, id2
, id3
, id4
, cnt
;
93 if (sscanf(line
, "%d%x%x%x%x%n", &cat
, &id1
, &id2
, &id3
, &id4
, &cnt
) >= 5)
96 while (*p
&& *p
== ' ')
98 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, p
, SRC_CACHE
);
103 a
->warning("Malformed cache file %s (line %d), ignoring", name
, lino
);
108 a
->warning("Error while reading %s", name
);
114 pci_id_cache_flush(struct pci_access
*a
)
116 int orig_status
= a
->id_cache_status
;
119 struct id_entry
*e
, *e2
;
120 char hostname
[256], *tmpname
, *name
;
123 a
->id_cache_status
= 0;
126 name
= get_cache_name(a
);
131 if (gethostname(hostname
, sizeof(hostname
)) < 0)
134 hostname
[sizeof(hostname
)-1] = 0;
135 tmpname
= pci_malloc(a
, strlen(name
) + strlen(hostname
) + 64);
136 sprintf(tmpname
, "%s.tmp-%s-%d", name
, hostname
, this_pid
);
138 f
= fopen(tmpname
, "wb");
141 a
->warning("Cannot write to %s: %s", name
, strerror(errno
));
145 a
->debug("Writing cache to %s\n", name
);
146 fprintf(f
, "%s\n", cache_version
);
148 for (h
=0; h
<HASH_SIZE
; h
++)
149 for (e
=a
->id_hash
[h
]; e
; e
=e
->next
)
150 if (e
->src
== SRC_CACHE
|| e
->src
== SRC_NET
)
152 /* Negative entries are not written */
156 /* Verify that every entry is written at most once */
157 for (e2
=a
->id_hash
[h
]; e2
!= e
; e2
=e2
->next
)
158 if ((e2
->src
== SRC_CACHE
|| e2
->src
== SRC_NET
) &&
160 e2
->id12
== e
->id12
&& e2
->id34
== e
->id34
)
163 fprintf(f
, "%d %x %x %x %x %s\n",
165 pair_first(e
->id12
), pair_second(e
->id12
),
166 pair_first(e
->id34
), pair_second(e
->id34
),
172 a
->warning("Error writing %s", name
);
175 if (rename(tmpname
, name
) < 0)
177 a
->warning("Cannot rename %s to %s: %s", tmpname
, name
, strerror(errno
));
185 int pci_id_cache_load(struct pci_access
*a UNUSED
, int flags UNUSED
)
187 a
->id_cache_status
= 1;
191 void pci_id_cache_flush(struct pci_access
*a
)
193 a
->id_cache_status
= 0;
199 pci_id_cache_dirty(struct pci_access
*a
)
201 if (a
->id_cache_status
>= 1)
202 a
->id_cache_status
= 2;