added updatedb.c and argmax.c.
[findutils.git] / locate / updatedb.c
blob88d9cdc9cb31479b24ef5a7a1e78c95798a314b2
1 /*
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)
9 any later version.
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,
19 USA.
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 */
28 #include "locatedb.h"
30 //#include <sys/types.h>
31 #include <sys/wait.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <stdarg.h>
37 #include <getopt.h>
39 #include "../gnulib/lib/tempname.h"
40 #include "../gnulib/lib/error.h"
43 * 1. find
44 * 2. sort
45 * 3. encode
46 * 4. write
48 * we need to be very portable, so use several approaches varying in
49 * performance.
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
62 * script
64 * the following environment variables and command-line arguments affect this
65 * program:
67 * - FINDOPTIONS
68 * - SHELL
69 * - SEARCHPATHS
70 * - NETPATHS
71 * - PRUNEPATHS
72 * - PRUNEREGEX
73 * - PRUNEFS
74 * - LOCATE_DB
75 * - NETUSER
76 * - LIBEXECDIR
77 * - BINDIR
79 * TODO:
81 * * remember temporary files and subprocesses and clean them
82 * up on signal/exit
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
88 * without issues
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
99 * 3. defaults
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.
106 struct map
108 char *key;
109 char *value;
112 static struct map DEFAULTS[] =
114 { "PRUNEFS", "/proc" },
115 { "LOCATE_DB", "/etc/locatedb"},
116 NULL
119 struct config
121 char *findoptions;
122 char *shell;
123 char *searchpaths;
124 char *netpaths;
125 char *prunepaths;
126 char *pruneregex;
127 char *prunefs;
128 char *locate_db;
129 char *netuser;
130 char *libexecdir;
131 char *bindir;
132 char *tmpdir;
134 char *changeto;
136 int old_format;
139 static struct config CFG =
141 "", /* findoptions */
142 "/bin/sh", /* shell */
143 "", /* searchpaths */
144 "", /* netpaths */
145 "/tmp /usr/tmp /var/tmp /afs /amd /sfs /proc", /* prunepaths */
146 "", /* pruneregex */
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 */
151 BINDIR /* bindir */
152 "", /* tmpdir */
153 "/", /* changeto */
154 0 /* old_format */
159 #define xgetenv(var, default) \
160 (getenv(var) != NULL ? getenv(var) : default)
162 static char*
163 sprintf_alloc(char *target, const char *fmt, ...)
168 static void
169 xsystem(char *cmd)
171 int r = system(cmd);
173 if (r == -1)
174 error(1, 0, "failed to fork");
175 else
176 printf("exit status of %s: %d\n", cmd, WEXITSTATUS(r));
178 return;
182 static char*
183 get_default(char *key)
185 struct map *m = DEFAULTS;
187 while (m)
189 if (strcmp(m->key, key) == 0)
190 return m->value;
191 m++;
194 return ""; /* no default */
198 static void
199 updatedb_dumb()
201 /* XXX temporary defines */
202 #if 0
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);
208 char *find_command;
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");
216 #endif
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");
227 #endif
228 return;
231 static void
232 usage(FILE* out)
234 fprintf(out,
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"
240 "\n"
241 "Report bugs to <bug-findutils@gnu.org>.");
243 return;
246 static void
247 parse_options(int* ac, char*** av)
249 enum option_ids /* return values for getopt_long */
251 OPT_FINDOPTIONS,
252 OPT_SHELL,
253 OPT_SEARCHPATHS,
254 OPT_NETPATHS,
255 OPT_PRUNEPATHS,
256 OPT_PRUNEREGEX,
257 OPT_PRUNEFS,
258 OPT_LOCATE_DB,
259 OPT_NETUSER,
260 OPT_LIBEXECDIR,
261 OPT_BINDIR,
262 OPT_CHANGECWD
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}
288 int optc;
290 while ((optc = getopt_long (*ac, *av, "h", longopts, (int *) 0)) != -1)
291 switch (optc)
293 case 'h':
294 usage(stdout);
295 exit(EXIT_SUCCESS);
296 break;
298 case 'v':
300 case OPT_FINDOPTIONS:
301 break;
303 case OPT_SHELL:
304 break;
306 case OPT_SEARCHPATHS:
307 break;
309 case OPT_NETPATHS:
310 break;
312 case OPT_PRUNEPATHS:
313 break;
315 case OPT_PRUNEREGEX:
316 break;
318 case OPT_PRUNEFS:
319 break;
321 case OPT_LOCATE_DB:
322 break;
324 case OPT_NETUSER:
325 break;
327 case OPT_LIBEXECDIR:
328 break;
330 case OPT_BINDIR:
331 break;
333 case OPT_CHANGECWD:
334 break;
336 default:
337 usage(stderr);
338 exit(EXIT_FAILURE);
343 static void
344 build_config()
352 main (int argc, char **argv)
354 updatedb_dumb();
356 printf("%s\n", get_default("PRUNEFS"));
358 parse_options (&argc, &argv);
360 return 0;