da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * original code
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * James A. Woods, Informatics General Corporation,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NASA Ames Research Center, 6/81.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Usenix ;login:, February/March, 1983, p. 8.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * discipline/method interface
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * modified from the original BSD source
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 'fastfind' scans a file list for the full pathname of a file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * given only a piece of the name. The list is processed with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * with "front-compression" and bigram coding. Front compression reduces
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * space by a factor of 4-5, bigram coding by a further 20-25%.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * there are 4 methods:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_old original with 7 bit bigram encoding (no magic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_gnu 8 bit clean front compression (FF_gnu_magic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_dir FF_gnu with sfgetl/sfputl and trailing / on dirs (FF_dir_magic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_typ FF_dir with (mime) types (FF_typ_magic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the bigram encoding steals the eighth bit (that's why its FF_old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * maybe one day we'll limit it to readonly:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0-2*FF_OFF likeliest differential counts + offset to make nonnegative
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_ESC 4 byte big-endian out-of-range count+FF_OFF follows
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_MIN-FF_MAX ascii residue
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * >=FF_MAX bigram codes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a two-tiered string search technique is employed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a metacharacter-free subpattern and partial pathname is matched
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * backwards to avoid full expansion of the pathname list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * then the actual shell glob-style regular expression (if in this form)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is matched against the candidate pathnames using the slower regexec()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The original BSD code is covered by the BSD license:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright (c) 1985, 1993, 1999
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The Regents of the University of California. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Redistribution and use in source and binary forms, with or without
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * modification, are permitted provided that the following conditions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * are met:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1. Redistributions of source code must retain the above copyright
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * notice, this list of conditions and the following disclaimer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 2. Redistributions in binary form must reproduce the above copyright
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * notice, this list of conditions and the following disclaimer in the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * documentation and/or other materials provided with the distribution.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 3. Neither the name of the University nor the names of its contributors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * may be used to endorse or promote products derived from this software
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * without specific prior written permission.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * SUCH DAMAGE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char id[] = "\n@(#)$Id: fastfind (AT&T Research) 2002-10-02 $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char lib[] = "libast:fastfind";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "findlib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FIND_MATCH "*/(find|locate)/*"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this db could be anywhere
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * findcodes[] directories are checked for findnames[i]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* findcodes[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FIND_CODES,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/usr/local/share/lib",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/usr/local/lib",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/usr/share/lib",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/usr/lib",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/var/spool",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/usr/local/var",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/var/lib",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/var/lib/slocate",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "/var/db",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* findnames[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "find/codes",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "find/find.codes",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "locate/locatedb",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "locatedb",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "locate.database",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "slocate.db",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert t to lower case and drop leading x- and x- after /
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * converted value copied to b of size n
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypefix(char* buf, size_t n, register const char* t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* b = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*t == 'x' || *t == 'X') && *(t + 1) == '-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *t++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = tolower(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*b++ = c) == '/' && (*t == 'x' || *t == 'X') && *(t + 1) == '-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return a fastfind stream handle for pattern
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFind_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfindopen(const char* file, const char* pattern, const char* type, Finddisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Find_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int brace = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int paren = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int uid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Type_t* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: searching for FIND_CODES would be much simpler if we
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * just stuck with our own, but we also support GNU
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * locate codes and have to search for the one of a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * bazillion possible names for that file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!findcodes[1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin findcodes[1] = getenv(FIND_CODES_ENV);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->flags & FIND_GENERATE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp = (Find_t*)vmnewof(vm, 0, Find_t, 1, sizeof(Encode_t) - sizeof(Code_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->vm = vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->id = lib;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->disc = disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->generate = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (file && (!*file || streq(file, "-")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin file = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin uid = geteuid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = (findcodes[0] = (char*)file) && *file == '/' ? 1 : elementsof(findcodes);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * look for the codes file, but since it may not exist yet,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * also look for the containing directory if i<2 or if
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * it is sufficiently qualified (FIND_MATCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < j; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path = findcodes[i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*path == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(path, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISDIR(st.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = 0; k < elementsof(findnames); k++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s/%s", path, findnames[k]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!eaccess(fp->encode.file, R_OK|W_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strchr(findnames[k], '/') && (b = strrchr(fp->encode.file, '/')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(fp->encode.file, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (k < elementsof(findnames))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (st.st_uid == uid && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s", path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (i < 2 || strmatch(path, FIND_MATCH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s", path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b = strrchr(fp->encode.file, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(fp->encode.file, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pathpath(fp->encode.file, path, "", PATH_REGULAR|PATH_READ|PATH_WRITE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (b = strrchr(path, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%-.*s", b - path, path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pathpath(fp->encode.temp, fp->encode.file, "", PATH_EXECUTE|PATH_READ|PATH_WRITE) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin !stat(fp->encode.temp, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s%s", fp->encode.temp, b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i >= j)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot locate codes", file ? file : findcodes[2]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->flags & FIND_OLD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FF_old generates temp data that is read
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * in a second pass to generate the real codes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->fp = sftmp(32 * PATH_MAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "cannot create tmp file");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the rest generate into a temp file that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is simply renamed on completion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s = strrchr(path, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = ".";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pathtemp(fp->encode.temp, sizeof(fp->encode.temp), p, "ff", &fd))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot create tmp file in this directory", p ? p : ".");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->fp = sfnew(NiL, NiL, (size_t)SF_UNBOUND, fd, SF_WRITE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot open tmp file", fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->flags & FIND_TYPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_typ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.namedisc.key = offsetof(Type_t, name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.namedisc.link = offsetof(Type_t, byname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.indexdisc.key = offsetof(Type_t, index);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.indexdisc.size = sizeof(unsigned long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.indexdisc.link = offsetof(Type_t, byindex);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "system/dir";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->encode.namedict = dtopen(&fp->encode.namedisc, Dttree)) || !(fp->encode.indexdict = dtopen(&fp->encode.indexdisc, Dttree)) || !(tp = newof(0, Type_t, 1, strlen(s) + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->encode.namedict)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(fp->encode.namedict);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "cannot allocate type table");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * type index 1 is always system/dir
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->index = ++fp->types;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(tp->name, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(fp->encode.namedict, tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(fp->encode.indexdict, tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (fp->disc->flags & FIND_GNU)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_gnu;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->fp, FF_gnu_magic, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_dir;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->fp, FF_dir_magic, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = sizeof(Decode_t) + sizeof(Code_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pattern || !*pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pattern = "*";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i += (j = 2 * (strlen(pattern) + 1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp = (Find_t*)vmnewof(vm, 0, Find_t, 1, i)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->vm = vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->id = lib;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->disc = disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->flags & FIND_ICASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.ignorecase = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = (findcodes[0] = (char*)file) && *file == '/' ? 1 : elementsof(findcodes);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < j; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path = findcodes[i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*path == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!stat(path, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISDIR(st.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = 0; k < elementsof(findnames); k++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(fp->decode.path, sizeof(fp->decode.path), "%s/%s", path, findnames[k]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->fp = sfopen(NiL, fp->decode.path, "r"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->decode.path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (fp->fp = sfopen(NiL, path, "r"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((path = pathpath(fp->decode.path, path, "", PATH_REGULAR|PATH_READ)) && (fp->fp = sfopen(NiL, path, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot locate codes", file ? file : findcodes[2]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fstat(sffileno(fp->fp), &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot stat codes", path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->secure = ((st.st_mode & (S_IRGRP|S_IROTH)) == S_IRGRP) && st.st_gid == getegid() && getegid() != getgid())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setgid(getgid());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->stamp = st.st_mtime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (s = fp->decode.temp) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(fp->decode.bigram1); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((j = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*s++ = fp->decode.bigram1[i] = j) && i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = -i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((j = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*s++ = fp->decode.bigram2[i] = j) && (i || fp->decode.bigram1[0] >= '0' && fp->decode.bigram1[0] <= '1'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(b, FF_typ_magic))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = (const char*)typefix(fp->decode.bigram2, sizeof(fp->decode.bigram2), type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(fp->decode.bigram1, 0, sizeof(fp->decode.bigram1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_typ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (j = 0, i = 1;; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = sfgetr(fp->fp, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type && strmatch(s, type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FF_SET_TYPE(fp, i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type && !j)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->types = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (streq(b, FF_dir_magic))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_dir;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (streq(b, FF_gnu_magic))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_gnu;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!*b && *--b >= '0' && *b <= '1')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_gnu;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (j = sfgetc(fp->fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (j == EOF || fp->decode.count >= sizeof(fp->decode.path))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.path[fp->decode.count++] = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->method = FF_old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((j = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.bigram2[i = -i] = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (++i < elementsof(fp->decode.bigram1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((j = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.bigram1[i] = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((j = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.bigram2[i] = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fp->decode.peek = sfgetc(fp->fp)) != FF_OFF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up the physical dir table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->version >= 19980301L)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->verifyf = disc->verifyf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->dirs && *disc->dirs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = 0; disc->dirs[k]; k++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (k == 1 && streq(disc->dirs[0], "/"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (k)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->dirs = vmnewof(fp->vm, 0, char*, 2 * k + 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->lens = vmnewof(fp->vm, 0, int, 2 * k, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = fp->decode.temp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = fp->method == FF_old || fp->method == FF_gnu;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fill the dir list with logical and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * physical names since we don't know
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * which way the db was encoded (it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * could be *both* ways)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = q = 0; i < k; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(s = disc->dirs[i]) == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(b, sizeof(fp->decode.temp) - 1, "%s", s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!p && !(p = getcwd(fp->decode.path, sizeof(fp->decode.path))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(b, sizeof(fp->decode.temp) - 1, "%s/%s", p, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = pathcanon(b, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(s + 1) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->dirs[q] = vmstrdup(fp->vm, b)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (j)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (fp->dirs[q])[s - b] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = pathcanon(b, PATH_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(s + 1) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strneq(b, fp->dirs[q - 1], s - b))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->dirs[q] = vmstrdup(fp->vm, b)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (j)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (fp->dirs[q])[s - b] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strsort(fp->dirs, q, strcasecmp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < q; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->lens[i] = strlen(fp->dirs[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->verifyf || (disc->flags & FIND_VERIFY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->method != FF_dir && fp->method != FF_typ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s code format does not support directory verification", path, fp->method == FF_gnu ? FF_gnu_magic : "OLD-BIGRAM");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->verify = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * extract last glob-free subpattern in name for fast pre-match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * prepend 0 for backwards match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = s = (char*)pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = fp->decode.pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*b++ = *p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '[':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!brace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin brace++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ']':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (brace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin brace--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!brace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin paren++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!brace && paren > 0 && !--paren)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!brace && !paren)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '*':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s != pattern && !streq(pattern, "*"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.match = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i = regcomp(&fp->decode.re, pattern, REG_SHELL|REG_AUGMENTED|(fp->decode.ignorecase?REG_ICASE:0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regerror(i, &fp->decode.re, fp->decode.temp, sizeof(fp->decode.temp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s", pattern, fp->decode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (i = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b-- = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.end = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.ignorecase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = fp->decode.pattern; s <= b; s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isupper(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = tolower(*s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nospace:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!vm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto drop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin invalid:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: invalid codes", path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->generate && fp->decode.match)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(&fp->decode.re);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(fp->vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the next fastfind path
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned when list exhausted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfindread(register Find_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ignorecase;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char w[4];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->generate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.restore)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fp->decode.restore = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.restore = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ignorecase = fp->decode.ignorecase ? STR_ICASE : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fp->decode.peek;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (fp->method)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_dir:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfgetl(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto grab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_gnu:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = c << 8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n & 0x8000)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (n - 0xffff) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((n = c) & 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (n - 0xff) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto grab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_typ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = sfgetu(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfgetl(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin grab:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = fp->decode.path + (fp->decode.count += n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = sfgetc(fp->fp)) == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (*p++ = c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p -= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_old:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.peek = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == FF_ESC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfread(fp->fp, w, sizeof(w)) != sizeof(w))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.swap >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (int32_t)((w[0] << 24) | (w[1] << 16) | (w[2] << 8) | w[3]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->decode.swap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the old format uses machine
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * byte order; this test uses
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the smallest magnitude of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * both byte orders on the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * first encoded path motion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to determine the original
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * byte order
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = -m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = -n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.swap = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.swap = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.count += c - FF_OFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p = fp->decode.path + fp->decode.count; (c = sfgetc(fp->fp)) > FF_ESC;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & (1<<(CHAR_BIT-1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = fp->decode.bigram1[c & ((1<<(CHAR_BIT-1))-1)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = fp->decode.bigram2[c & ((1<<(CHAR_BIT-1))-1)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p-- = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = fp->decode.path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.found)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.found = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += fp->decode.count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->dirs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*fp->dirs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * use the ordering and lengths to prune
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * comparison function calls
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (*fp->dirs)[*fp->lens]=='/' if its
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * already been matched
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = p - fp->decode.path + 1) > (m = *fp->lens))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*fp->dirs)[m])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncasecmp(*fp->dirs, fp->decode.path, m))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n == m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*fp->dirs)[m])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n = strcasecmp(*fp->dirs, fp->decode.path)) && (ignorecase || !strcmp(*fp->dirs, fp->decode.path)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->dirs)[m] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*fp->dirs)[m - 1] != '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->dirs)[++(*fp->lens)] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(*fp->dirs)[m])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->dirs++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->lens++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->verify && (*p == '/' || t == 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = p - fp->decode.path))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->verifyf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (*fp->verifyf)(fp, fp->decode.path, n, fp->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (stat(fp->decode.path, &st))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((unsigned long)st.st_mtime > fp->stamp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * n<0 skip this subtree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * n==0 keep as is
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * n>0 read this dir now
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOT IMPLEMENTED YET */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (FF_OK_TYPE(fp, t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.end)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(s = p) == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*fp->decode.pattern == '/' && b > fp->decode.path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; s >= b; s--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == *fp->decode.end || ignorecase && tolower(*s) == *fp->decode.end)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ignorecase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (e = fp->decode.end - 1, q = s - 1; *e && (*q == *e || tolower(*q) == *e); e--, q--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (e = fp->decode.end - 1, q = s - 1; *e && *q == *e; e--, q--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.found = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->decode.match || strgrpmatch(fp->decode.path, fp->decode.pattern, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|ignorecase))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.peek = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(fp->decode.restore = p) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->secure || !access(fp->decode.path, F_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fp->decode.path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!fp->decode.match || !(n = regexec(&fp->decode.re, fp->decode.path, 0, NiL, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->decode.peek = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p == '/' && p > fp->decode.path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(fp->decode.restore = p) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->secure || !access(fp->decode.path, F_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fp->decode.path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n != REG_NOMATCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regerror(n, &fp->decode.re, fp->decode.temp, sizeof(fp->decode.temp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s", fp->decode.pattern, fp->decode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add path to the code table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * paths are assumed to be in sort order
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfindwrite(register Find_t* fp, const char* path, size_t len, const char* type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Type_t* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned long u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->generate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type && fp->method == FF_dir)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = sfsprintf(fp->encode.mark, sizeof(fp->encode.mark), "%-.*s/", len, path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = fp->encode.mark;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (unsigned char*)path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (len <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = strlen(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (len < sizeof(fp->encode.path))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = s + len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = sizeof(fp->encode.path) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = s + len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = (unsigned char*)fp->encode.path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s != *p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = s - (unsigned char*)path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (fp->method)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_gnu:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = n - fp->encode.prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (d >= -127 && d <= 127)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, d & 0xff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, 0x80);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, (d >> 8) & 0xff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, d & 0xff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.prefix = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->fp, (char*)s, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_old:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(fp->fp, "%ld", n - fp->encode.prefix + FF_OFF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.prefix = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s >= e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.code[n][*s++]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = *p++) < FF_MIN || n >= FF_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->fp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_typ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = (const char*)typefix((char*)fp->encode.bigram, sizeof(fp->encode.bigram), type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x = (Type_t*)dtmatch(fp->encode.namedict, type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u = x->index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(x = newof(0, Type_t, 1, strlen(type) + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u = x->index = ++fp->types;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(x->name, type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(fp->encode.namedict, x);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(fp->encode.indexdict, x);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputu(fp->fp, u);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_dir:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = n - fp->encode.prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputl(fp->fp, d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.prefix = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->fp, (char*)s, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(fp->encode.path, path, len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * findsync() helper
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfinddone(register Find_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfsync(fp->fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sfsync]", fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sferror(fp->fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sferror]", fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->fp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (r)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sfclose]", fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * finish the code table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfindsync(register Find_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Type_t* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long z;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (fp->method)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_dir:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_gnu:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * replace the real file with the temp file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (finddone(fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (rename(fp->encode.temp, fp->encode.file))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot rename from tmp file %s", fp->encode.file, fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_old:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * determine the top FF_MAX bigrams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < FF_MAX; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m < FF_MAX; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.hits[fp->encode.code[n][m]]++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.hits[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = USHRT_MAX; n >= 0; n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (d = fp->encode.hits[n])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.hits[n] = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((m += d) > FF_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--n >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.hits[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = FF_MAX - 1; n >= 0; n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = FF_MAX - 1; m >= 0; m--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->encode.hits[fp->encode.code[n][m]])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = fp->encode.code[n][m];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = fp->encode.hits[d] - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.code[n][m] = b + FF_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->encode.hits[d]++ >= FF_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.hits[d] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.bigram[b *= 2] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.bigram[b + 1] = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->encode.code[n][m] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * commit the real file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfseek(fp->fp, (Sfoff_t)0, SEEK_SET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "cannot rewind tmp file");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sp = sfopen(NiL, fp->encode.file, "w")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto badcreate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump the bigrams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sp, fp->encode.bigram, sizeof(fp->encode.bigram));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * encode the massaged paths
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s = sfgetr(fp->fp, 0, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin z = strtol(s, &t, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (z < 0 || z > 2 * FF_OFF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, FF_ESC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, (z >> 24));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, (z >> 16));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, (z >> 8));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, z);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, z);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(m = *s++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (d = fp->encode.code[n][m])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->fp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (finddone(fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FF_typ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (finddone(fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fp->fp = sfopen(NiL, fp->encode.temp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot read tmp file", fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * commit the output file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sp = sfopen(NiL, fp->encode.file, "w")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto badcreate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write the header magic
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp, FF_typ_magic, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write the type table in index order starting with 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (x = (Type_t*)dtfirst(fp->encode.indexdict); x; x = (Type_t*)dtnext(fp->encode.indexdict, x))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp, x->name, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * append the front compressed strings
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfmove(fp->fp, sp, SF_UNBOUND, -1) < 0 || !sfeof(fp->fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot append codes", fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->fp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (finddone(fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin badcreate:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->disc->errorf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot write codes", fp->encode.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->fp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(fp->encode.temp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close an open fastfind stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfindclose(register Find_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->generate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = findsync(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->encode.indexdict)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(fp->encode.indexdict);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->encode.namedict)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(fp->encode.namedict);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->decode.match)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(&fp->decode.re);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp->fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmclose(fp->vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}