blob: e2ccafd260c0f85ed7b7f4f5fc16ad4fa7635d51 [file] [log] [blame]
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -05001/*
2 * cache.c - allocation/initialization/free routines for cache
3 *
4 * Copyright (C) 2001 Andreas Dilger
Theodore Ts'o50b380b2003-02-12 23:51:21 -05005 * Copyright (C) 2003 Theodore Ts'o
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -05006 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 * %End-Header%
11 */
12
JP Abgralle0ed7402014-03-19 19:08:39 -070013#if HAVE_SECURE_GETENV
14#define _GNU_SOURCE
15#endif
Theodore Ts'o762c7c62005-04-06 14:44:16 -040016#if HAVE_UNISTD_H
17#include <unistd.h>
18#endif
19#ifdef HAVE_ERRNO_H
20#include <errno.h>
21#endif
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050022#include <stdlib.h>
Theodore Ts'o48e6e812003-07-06 00:36:48 -040023#include <string.h>
Theodore Ts'o762c7c62005-04-06 14:44:16 -040024#ifdef HAVE_SYS_PRCTL_H
25#include <sys/prctl.h>
26#else
27#define PR_GET_DUMPABLE 3
28#endif
29#if (!defined(HAVE_PRCTL) && defined(linux))
30#include <sys/syscall.h>
31#endif
Theodore Ts'o72923552007-05-18 00:02:35 -040032#ifdef HAVE_SYS_STAT_H
33#include <sys/stat.h>
34#endif
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050035#include "blkidP.h"
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050036
Theodore Ts'o88fe61c2003-03-17 18:13:57 -050037int blkid_debug_mask = 0;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050038
Theodore Ts'o762c7c62005-04-06 14:44:16 -040039
40static char *safe_getenv(const char *arg)
41{
Theodore Ts'o09f3eba2005-04-16 13:56:03 -040042 if ((getuid() != geteuid()) || (getgid() != getegid()))
Theodore Ts'o762c7c62005-04-06 14:44:16 -040043 return NULL;
44#if HAVE_PRCTL
Theodore Ts'o583d1f82005-07-25 11:36:43 -050045 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
Theodore Ts'o762c7c62005-04-06 14:44:16 -040046 return NULL;
47#else
48#if (defined(linux) && defined(SYS_prctl))
Theodore Ts'o583d1f82005-07-25 11:36:43 -050049 if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
Theodore Ts'o762c7c62005-04-06 14:44:16 -040050 return NULL;
51#endif
52#endif
53
JP Abgralle0ed7402014-03-19 19:08:39 -070054#if defined(HAVE_SECURE_GETENV)
55 return secure_getenv(arg);
56#elif defined(HAVE___SECURE_GETENV)
Theodore Ts'o12b3c8e2005-05-07 14:38:10 -040057 return __secure_getenv(arg);
Theodore Ts'o762c7c62005-04-06 14:44:16 -040058#else
Theodore Ts'o12b3c8e2005-05-07 14:38:10 -040059 return getenv(arg);
Theodore Ts'o762c7c62005-04-06 14:44:16 -040060#endif
61}
62
Theodore Ts'o78c7d0e2005-05-07 14:22:38 -040063#if 0 /* ifdef CONFIG_BLKID_DEBUG */
64static blkid_debug_dump_cache(int mask, blkid_cache cache)
65{
66 struct list_head *p;
67
68 if (!cache) {
69 printf("cache: NULL\n");
70 return;
71 }
72
73 printf("cache: time = %lu\n", cache->bic_time);
74 printf("cache: flags = 0x%08X\n", cache->bic_flags);
75
76 list_for_each(p, &cache->bic_devs) {
77 blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
78 blkid_debug_dump_dev(dev);
79 }
80}
81#endif
82
Theodore Ts'o79dd2342003-02-22 17:15:20 -050083int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050084{
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050085 blkid_cache cache;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050086
Theodore Ts'of0a22d02003-02-22 13:19:53 -050087#ifdef CONFIG_BLKID_DEBUG
88 if (!(blkid_debug_mask & DEBUG_INIT)) {
89 char *dstr = getenv("BLKID_DEBUG");
90
91 if (dstr)
92 blkid_debug_mask = strtoul(dstr, 0, 0);
93 blkid_debug_mask |= DEBUG_INIT;
94 }
95#endif
96
Theodore Ts'o79dd2342003-02-22 17:15:20 -050097 DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
98 filename ? filename : "default cache"));
Theodore Ts'of0a22d02003-02-22 13:19:53 -050099
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500100 if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
Theodore Ts'o79dd2342003-02-22 17:15:20 -0500101 return -BLKID_ERR_MEM;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500102
103 INIT_LIST_HEAD(&cache->bic_devs);
104 INIT_LIST_HEAD(&cache->bic_tags);
105
Theodore Ts'o7a3a3862004-04-12 07:26:23 -0400106 if (filename && !strlen(filename))
107 filename = 0;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400108 if (!filename)
Theodore Ts'o762c7c62005-04-06 14:44:16 -0400109 filename = safe_getenv("BLKID_FILE");
Theodore Ts'o7a3a3862004-04-12 07:26:23 -0400110 if (!filename)
Theodore Ts'o79dd2342003-02-22 17:15:20 -0500111 filename = BLKID_CACHE_FILE;
112 cache->bic_filename = blkid_strdup(filename);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400113
Theodore Ts'o79dd2342003-02-22 17:15:20 -0500114 blkid_read_cache(cache);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400115
Theodore Ts'o79dd2342003-02-22 17:15:20 -0500116 *ret_cache = cache;
117 return 0;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500118}
119
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500120void blkid_put_cache(blkid_cache cache)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500121{
122 if (!cache)
123 return;
124
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500125 (void) blkid_flush_cache(cache);
126
Theodore Ts'of0a22d02003-02-22 13:19:53 -0500127 DBG(DEBUG_CACHE, printf("freeing cache struct\n"));
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400128
Theodore Ts'o78c7d0e2005-05-07 14:22:38 -0400129 /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500130
131 while (!list_empty(&cache->bic_devs)) {
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500132 blkid_dev dev = list_entry(cache->bic_devs.next,
133 struct blkid_struct_dev,
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500134 bid_devs);
135 blkid_free_dev(dev);
136 }
137
138 while (!list_empty(&cache->bic_tags)) {
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500139 blkid_tag tag = list_entry(cache->bic_tags.next,
140 struct blkid_struct_tag,
141 bit_tags);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500142
143 while (!list_empty(&tag->bit_names)) {
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500144 blkid_tag bad = list_entry(tag->bit_names.next,
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400145 struct blkid_struct_tag,
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500146 bit_names);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500147
Theodore Ts'of0a22d02003-02-22 13:19:53 -0500148 DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
149 bad->bit_name, bad->bit_val));
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500150 blkid_free_tag(bad);
151 }
152 blkid_free_tag(tag);
153 }
Jim Meyering45e338f2009-02-23 18:07:50 +0100154 free(cache->bic_filename);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400155
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500156 free(cache);
157}
158
Theodore Ts'o72923552007-05-18 00:02:35 -0400159void blkid_gc_cache(blkid_cache cache)
160{
Eric Sandeen772b89d2008-06-20 22:32:49 -0500161 struct list_head *p, *pnext;
Theodore Ts'o72923552007-05-18 00:02:35 -0400162 struct stat st;
163
164 if (!cache)
165 return;
166
Eric Sandeen772b89d2008-06-20 22:32:49 -0500167 list_for_each_safe(p, pnext, &cache->bic_devs) {
Theodore Ts'o72923552007-05-18 00:02:35 -0400168 blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
169 if (!p)
170 break;
171 if (stat(dev->bid_name, &st) < 0) {
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400172 DBG(DEBUG_CACHE,
Theodore Ts'o72923552007-05-18 00:02:35 -0400173 printf("freeing %s\n", dev->bid_name));
174 blkid_free_dev(dev);
175 cache->bic_flags |= BLKID_BIC_FL_CHANGED;
176 } else {
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400177 DBG(DEBUG_CACHE,
Theodore Ts'o72923552007-05-18 00:02:35 -0400178 printf("Device %s exists\n", dev->bid_name));
179 }
180 }
181}
182
183
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500184#ifdef TEST_PROGRAM
185int main(int argc, char** argv)
186{
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500187 blkid_cache cache = NULL;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500188 int ret;
189
Theodore Ts'of0a22d02003-02-22 13:19:53 -0500190 blkid_debug_mask = DEBUG_ALL;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500191 if ((argc > 2)) {
192 fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
193 exit(1);
194 }
195
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500196 if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500197 fprintf(stderr, "error %d parsing cache file %s\n", ret,
198 argv[1] ? argv[1] : BLKID_CACHE_FILE);
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500199 exit(1);
200 }
Theodore Ts'o79dd2342003-02-22 17:15:20 -0500201 if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
202 fprintf(stderr, "%s: error creating cache (%d)\n",
203 argv[0], ret);
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500204 exit(1);
205 }
206 if ((ret = blkid_probe_all(cache) < 0))
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500207 fprintf(stderr, "error probing devices\n");
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500208
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500209 blkid_put_cache(cache);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500210
211 return ret;
212}
213#endif