2 updatedb -- build a locate pathname database
4 Copyright (C) 2007 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 csh original by James Woods; sh conversion by David MacKenzie.
22 Rewrite in C by Leslie P. Polzer based on a proposal by James Youngman.
26 #define STR(a) printf("STR: %s=%s\n", #a, a); /* FIXME: debug */
30 //#include <sys/types.h>
39 #include "../gnulib/lib/tempname.h"
40 #include "../gnulib/lib/error.h"
48 * we need to be very portable, so use several approaches varying in
51 * in order of preference:
53 * - use pthreads or clone(), exec() and a shared piece of memory that
54 * naturally comes with them. do as many things as possible in memory
55 * while waiting on disk i/o generated by ``find''.
57 * - use fork(), exec() and a shared memory area obtained with shmget()
59 * - vfork is avoided as we can't rely on it.
61 * - use temporary files for everything as in the original updatedb shell
64 * the following environment variables and command-line arguments affect this
81 * * remember temporary files and subprocesses and clean them
84 * * give up root privileges whenever possible (see seteuid(3),
85 * probably POSIX capabilities). see locate.c.
87 * * updatedb needs to be callable by an ordinary user
90 * * -q switch for only serious errors
92 * (* -q -q switch for not even serious errors)
95 * Configuration system:
97 * 1. command-line arguments
98 * 2. environment variables
101 * strategy: we fill in 1) with getopt. then we fill in the empty
102 * strings with stuff from the env. after that, still empty strings
103 * get filled with their defaults.
112 static struct map DEFAULTS
[] =
114 { "PRUNEFS", "/proc" },
115 { "LOCATE_DB", "/etc/locatedb"},
139 static struct config CFG
=
141 "", /* findoptions */
142 "/bin/sh", /* shell */
143 "", /* searchpaths */
145 "/tmp /usr/tmp /var/tmp /afs /amd /sfs /proc", /* prunepaths */
147 "nfs NFS proc afs proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs sysfs shfs", /* prunefs */
148 LOCATE_DB
, /* locate_db */
149 "daemon", /* netuser */
150 LIBEXECDIR
, /* libexecdir */
159 #define xgetenv(var, default) \
160 (getenv(var) != NULL ? getenv(var) : default)
163 sprintf_alloc(char *target
, const char *fmt
, ...)
174 error(1, 0, "failed to fork");
176 printf("exit status of %s: %d\n", cmd
, WEXITSTATUS(r
));
183 get_default(char *key
)
185 struct map
*m
= DEFAULTS
;
189 if (strcmp(m
->key
, key
) == 0)
194 return ""; /* no default */
201 /* XXX temporary defines */
203 #define BINDIR "/usr/bin"
204 char *tmp_find
= strdup("updatedb.find.XXXXXX");
205 char *tmp_sort
= strdup("updatedb.sort.XXXXXX");
206 char *tmp_frcode
= strdup("updatedb.frcode.XXXXXX");
207 char *bindir
= xgetenv("BINDIR", BINDIR
);
209 char *find_invocation
= malloc(MAC2048
);
211 find_command
= malloc(strlen(BINDIR
) + 4 + 1);
212 strcpy(find_command
, bindir
);
213 strcat(find_command
, "/find");
214 #ifdef SORT_SUPPORTS_Z
215 strcat(find_command
, " -print0");
218 gen_tempname(tmp_find
, GT_NOCREATE
);
219 xsystem("find /home/sky/tmp/TESTDIR -print0 > /tmp/tmp.find");
221 gen_tempname(tmp_sort
, GT_NOCREATE
);
222 xsystem("sort -f -z /tmp/tmp.find > /tmp/tmp.sort");
224 gen_tempname(tmp_frcode
, GT_NOCREATE
);
225 xsystem("/usr/libexec/frcode < /tmp/tmp.sort > /tmp/tmp.frcode");
235 "Usage: updatedb [--findoptions='-option1 -option2...']\n"
236 "\t[--localpaths='dir1 dir2...'] [--netpaths='dir1 dir2...']\n"
237 "\t[--prunepaths='dir1 dir2...'] [--prunefs='fs1 fs2...']\n"
238 "\t[--output=dbfile] [--netuser=user] [--localuser=user]\n"
239 "\t[--old-format] [--version] [--help]\n"
241 "Report bugs to <bug-findutils@gnu.org>.");
247 parse_options(int* ac
, char*** av
)
249 enum option_ids
/* return values for getopt_long */
265 static struct option
const longopts
[] =
267 {"findoptions", required_argument
, NULL
, OPT_FINDOPTIONS
},
268 {"shell", required_argument
, NULL
, OPT_SHELL
},
269 {"localpaths", required_argument
, NULL
, OPT_SEARCHPATHS
},
270 {"netpaths", required_argument
, NULL
, OPT_NETPATHS
},
271 {"prunepaths", required_argument
, NULL
, OPT_PRUNEPATHS
},
272 {"pruneregex", required_argument
, NULL
, OPT_PRUNEREGEX
},
273 {"prunefs", required_argument
, NULL
, OPT_PRUNEFS
},
274 {"output", required_argument
, NULL
, OPT_LOCATE_DB
},
275 {"netuser", required_argument
, NULL
, OPT_NETUSER
},
276 {"libexecdir", required_argument
, NULL
, OPT_LIBEXECDIR
},
277 {"bindir", required_argument
, NULL
, OPT_BINDIR
},
278 {"changecwd", required_argument
, NULL
, OPT_CHANGECWD
},
280 {"old-format", no_argument
, &CFG
.old_format
, 1},
282 {"help", required_argument
, NULL
, 'h'},
283 {"version", required_argument
, NULL
, 'v'},
285 {NULL
, no_argument
, NULL
, 0}
290 while ((optc
= getopt_long (*ac
, *av
, "h", longopts
, (int *) 0)) != -1)
300 case OPT_FINDOPTIONS
:
306 case OPT_SEARCHPATHS
:
352 main (int argc
, char **argv
)
356 printf("%s\n", get_default("PRUNEFS"));
358 parse_options (&argc
, &argv
);