#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/stat.h>
#include "locate.h"
#include "pathnames.h"
char **colon(char **, char*, char*);
char *patprep(char *);
u_char *tolower_word(u_char *);
int getwm(caddr_t);
int getwf(FILE *);
int check_bigram_char(int);
int
check_bigram_char(int ch)
{
if (ch == 0 ||
(ch >= ASCII_MIN && ch <= ASCII_MAX))
return (ch);
errx(1,
"locate database header corrupt, bigram char outside 0, %d-%d: %d",
ASCII_MIN, ASCII_MAX, ch);
exit(1);
}
char **
colon(char **dbv, char *path, char *dot)
{
int vlen, slen;
char *c, *ch, *p;
char **pv;
if (dbv == NULL) {
if ((dbv = malloc(sizeof(char *))) == NULL)
err(1, "malloc");
*dbv = NULL;
}
if (*path == '\0') {
warnx("empty database name, ignored");
return (dbv);
}
for(vlen = 0, pv = dbv; *pv != NULL; pv++, vlen++);
for (ch = c = path; ; ch++) {
if (*ch == ':' ||
(!*ch && !(*(ch - 1) == ':' && ch == 1+ path))) {
if (ch == c)
p = dot;
else {
slen = ch - c;
if ((p = malloc(sizeof(char) * (slen + 1)))
== NULL)
err(1, "malloc");
bcopy(c, p, slen);
*(p + slen) = '\0';
}
if ((dbv = realloc(dbv, sizeof(char *) * (vlen + 2)))
== NULL)
err(1, "realloc");
*(dbv + vlen) = p;
*(dbv + ++vlen) = NULL;
c = ch + 1;
}
if (*ch == '\0')
break;
}
return (dbv);
}
static char globfree[100];
char *
patprep(char *name)
{
char *endmark, *p, *subp;
subp = globfree;
*subp++ = '\0';
p = name + strlen(name) - 1;
for (; p >= name; p--)
if (strchr(LOCATE_REG, *p) == NULL)
break;
if (p >= name &&
(strchr(p, '[') != NULL || strchr(p, ']') != NULL)) {
for (p = name; *p != '\0'; p++)
if (*p == ']' || *p == '[')
break;
p--;
if (p >= name && strchr(LOCATE_REG, *p) != NULL)
p = name - 1;
}
if (p < name)
*subp++ = '/';
else {
for (endmark = p; p >= name; p--)
if (strchr(LOCATE_REG, *p) != NULL)
break;
for (++p;
(p <= endmark) && subp < (globfree + sizeof(globfree));)
*subp++ = *p++;
}
*subp = '\0';
return (--subp);
}
u_char *
tolower_word(u_char *word)
{
u_char *p;
for(p = word; *p != '\0'; p++)
*p = TOLOWER(*p);
return (word);
}
int
getwm(caddr_t p)
{
union {
char buf[INTSIZE];
int i;
} u;
int i, hi;
int i_max = LOCATE_PATH_MAX + OFFSET;
int i_min = -(LOCATE_PATH_MAX - OFFSET);
for (i = 0; i < (int)INTSIZE; i++)
u.buf[i] = *p++;
i = u.i;
if (i >= i_max || i <= i_min) {
hi = ntohl(i);
if (hi >= i_max || hi <= i_min)
errx(1, "integer out of range: %d < %d < %d",
i_min, abs(i) < abs(hi) ? i : hi, i_max);
return (hi);
}
return (i);
}
int
getwf(FILE *fp)
{
int word, hword;
int i_max = LOCATE_PATH_MAX + OFFSET;
int i_min = -(LOCATE_PATH_MAX - OFFSET);
word = getw(fp);
if (word >= i_max || word <= i_min) {
hword = ntohl(word);
if (hword >= i_max || hword <= i_min)
errx(1, "integer out of range: %d < %d < %d",
i_min, abs(word) < abs(hword) ? word : hword, i_max);
return (hword);
}
return (word);
}
void
rebuild_message(char *db)
{
if (strcmp(_PATH_FCODES, db) == 0) {
fprintf(stderr, "\nTo create a new database, please run the following command as root:\n\n");
fprintf(stderr, " /etc/periodic/weekly/310.locate\n\n");
}
}
int
check_size(char *db)
{
struct stat sb;
off_t len;
if (stat(db, &sb) == -1) {
warnx("the locate database '%s' does not exist.", db);
rebuild_message(db);
return (0);
}
len = sb.st_size;
if (len < (2 * NBG)) {
warnx("the locate database '%s' is smaller than %d bytes large.", db, (2 * NBG));
rebuild_message(db);
return (0);
}
return (1);
}