]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names-cache.c
2 * The PCI Library -- ID to Name Cache
4 * Copyright (c) 2008--2009 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
18 #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
, 1);
43 return pci_get_param(a
, "net.cache_name");
47 pci_id_cache_load(struct pci_access
*a
, int flags
)
54 a
->id_cache_status
= 1;
55 name
= get_cache_name(a
);
58 a
->debug("Using cache %s\n", name
);
59 if (flags
& PCI_LOOKUP_REFRESH_CACHE
)
61 a
->debug("Not loading cache, will refresh everything\n");
62 a
->id_cache_status
= 2;
66 f
= fopen(name
, "rb");
69 a
->debug("Cache file does not exist\n");
72 /* FIXME: Compare timestamp with the pci.ids file? */
75 while (fgets(line
, sizeof(line
), f
))
77 char *p
= strchr(line
, '\n');
84 if (strcmp(line
, cache_version
))
86 a
->debug("Unrecognized cache version %s, ignoring\n", line
);
93 int cat
, id1
, id2
, id3
, id4
, cnt
;
94 if (sscanf(line
, "%d%x%x%x%x%n", &cat
, &id1
, &id2
, &id3
, &id4
, &cnt
) >= 5)
97 while (*p
&& *p
== ' ')
99 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, p
, SRC_CACHE
);
104 a
->warning("Malformed cache file %s (line %d), ignoring", name
, lino
);
109 a
->warning("Error while reading %s", name
);
115 pci_id_cache_flush(struct pci_access
*a
)
117 int orig_status
= a
->id_cache_status
;
120 struct id_entry
*e
, *e2
;
121 char hostname
[256], *tmpname
, *name
;
124 a
->id_cache_status
= 0;
127 name
= get_cache_name(a
);
132 if (gethostname(hostname
, sizeof(hostname
)) < 0)
135 hostname
[sizeof(hostname
)-1] = 0;
136 tmpname
= pci_malloc(a
, strlen(name
) + strlen(hostname
) + 64);
137 sprintf(tmpname
, "%s.tmp-%s-%d", name
, hostname
, this_pid
);
139 f
= fopen(tmpname
, "wb");
142 a
->warning("Cannot write to %s: %s", name
, strerror(errno
));
146 a
->debug("Writing cache to %s\n", name
);
147 fprintf(f
, "%s\n", cache_version
);
149 for (h
=0; h
<HASH_SIZE
; h
++)
150 for (e
=a
->id_hash
[h
]; e
; e
=e
->next
)
151 if (e
->src
== SRC_CACHE
|| e
->src
== SRC_NET
)
153 /* Negative entries are not written */
157 /* Verify that every entry is written at most once */
158 for (e2
=a
->id_hash
[h
]; e2
!= e
; e2
=e2
->next
)
159 if ((e2
->src
== SRC_CACHE
|| e2
->src
== SRC_NET
) &&
161 e2
->id12
== e
->id12
&& e2
->id34
== e
->id34
)
164 fprintf(f
, "%d %x %x %x %x %s\n",
166 pair_first(e
->id12
), pair_second(e
->id12
),
167 pair_first(e
->id34
), pair_second(e
->id34
),
173 a
->warning("Error writing %s", name
);
176 if (rename(tmpname
, name
) < 0)
178 a
->warning("Cannot rename %s to %s: %s", tmpname
, name
, strerror(errno
));
186 int pci_id_cache_load(struct pci_access
*a UNUSED
, int flags UNUSED
)
188 a
->id_cache_status
= 1;
192 void pci_id_cache_flush(struct pci_access
*a
)
194 a
->id_cache_status
= 0;
200 pci_id_cache_dirty(struct pci_access
*a
)
202 if (a
->id_cache_status
>= 1)
203 a
->id_cache_status
= 2;