/* mkfinfo.c -- Copyright 1995, 1996 Liam R. Quin. * All Rights Reserved. * This code is NOT in the public domain. * See the file COPYRIGHT for full details. */ /* * mkfinfo -- make a new FileInfo struct given the file name * * $Id: mkfinfo.c,v 1.7 2001/05/31 03:50:13 liam Exp $ * */ #include "globals.h" /* defines and declarations for database filenames */ #include "error.h" #include #include #include #include #include #ifndef FILE # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_STRING_H # include #else # include #endif #ifdef HAVE_STDLIB_H # include #else # include #endif #include "fileinfo.h" #include "lqutil.h" #include "liblqtext.h" #include "emalloc.h" #include "lqtrace.h" #include "filter.h" /** Unix system calls that need to be declared: **/ /** library functions that need to be declared: */ /** **/ /* * LQT_MakeFileInfo * Database/Update, Database/Documents * *

Creates a t_FileInfo structure to describe the given FileName. * This routine should only be used if you are going to add the * given FileName to the given lq-text Database db; to get a * FileInfo describing a file already in the index, * use LQT_NameToFID and LQT_FIDToFileInfo. * *

If the file is not already in the database, a new FID is allocated, * and a newly malloc'd t_FileInfo object is returned, complete with * a stdio FILE pointer already opened, either as a file or as a pipe, * depending on the file type and filter table; * it is the caller's responsibility to call LQT_DestroyFileInfo to * free the memory and close the stdio stream.

*

On error, or if the file is already in the database and has not * changed since it was last indexed, a warning is issued * and a NULL pointer is returned.

* * If the file can't be found, or can't be opened, a warning is * produced. * * LQT_DestroyFileInfo * LQT_NameToFID * LQT_FIDToFileInfo * LQT_GetFilterType * LQT_MakeInput *
*/ API t_FileInfo * LQT_MakeFileInfo(db, FileName) t_LQTEXT_Database *db; char *FileName; { #ifdef BSD extern time_t time(); #else extern long time(); #endif struct stat StatBuf; t_FileInfo *FileInfo = 0; t_FID FID; if (!FileName) { Error(E_INTERNAL, "LQT_MakeFileInfo called with NULL FileName"); return (t_FileInfo *) 0; } else if (!*FileName) { Error(E_INTERNAL, "LQT_MakeFileInfo called with empty FileName"); return (t_FileInfo *) 0; } if (stat(FileName, &StatBuf) < 0) { char *doc; if ((doc = LQT_FindFile(db, FileName)) == (char *) 0) { Error(E_WARN, "Can't find document file \"%s\"", FileName); return (t_FileInfo *) 0; } if (stat(doc, &StatBuf) < 0) { Error(E_WARN, "%s: can't stat document file \"%s\"", FileName, doc ); return (t_FileInfo *) 0; } FileName = doc; } if ((StatBuf.st_mode & S_IFMT) == S_IFDIR) { LQT_Trace(LQTRACE_VERBOSE|LQTRACE_DEBUG, "%s is a directory -- not indexed", FileName ); return (t_FileInfo *) 0; } if (StatBuf.st_size == 0L) { LQT_Trace(LQTRACE_VERBOSE|LQTRACE_DEBUG, "%s empty -- not indexed", FileName ); return (t_FileInfo *) 0; } /* See if it's in the index already: */ if ((FID = LQT_NameToFID(db, FileName)) != (t_FID) 0) { if ((FileInfo = LQT_FIDToFileInfo(db, FID)) != (t_FileInfo *) 0) { /* Check to see if the file has changed since it was last * indexed. If it has, we should delete the old one from * the database and give this one a new FID, but I have * not done that yet -- that's /usr/local/lib/lqtextd or * something, I suppose! */ if (FileInfo->Date >= StatBuf.st_mtime && FileInfo->FileSize == StatBuf.st_size) { LQT_Trace(LQTRACE_VERBOSE|LQTRACE_DEBUG, "%s unchanged since last run -- not indexed", FileName ); } else if (LQT_TraceFlagsSet(LQTRACE_VERBOSE|LQTRACE_DEBUG)) { Error(E_WARN, "%s changed since last run -- use lqupdate instead", FileName ); } LQT_DestroyFileInfo(db, FileInfo); return (t_FileInfo *) 0; } } else { FID = LQT_GetMaxOrAllocateFID(db, (long) StatBuf.st_size); } if (FileInfo == (t_FileInfo *) 0) { /* Allocate Structure */ FileInfo = (t_FileInfo *) emalloc("MakeFileInfo", sizeof(t_FileInfo)); /* Although not always necessary, call emalloc here so that a * FileInfo can always be deleted with LQT_DestroyFileInfo() */ FileInfo->Name = emalloc( "MakeFileInfo.Name", (unsigned)(strlen(FileName) + 1) ); (void) strcpy(FileInfo->Name, FileName); /* Other bits to set: */ FileInfo->Date = StatBuf.st_mtime; FileInfo->FileSize = StatBuf.st_size; FileInfo->Stream = 0; /* file type */ if ((FileInfo->FilterType = LQT_GetFilterType(db, FileInfo, &StatBuf)) < 0) { LQT_Trace(LQTRACE_VERBOSE|LQTRACE_DEBUG, "%s unknown file type -- not indexed", FileName ); LQT_DestroyFileInfo(db, FileInfo); return (t_FileInfo *) 0; } } FileInfo->FID = FID; FileInfo->Date = (long) time((long *) 0); /* it's a time_t on BSD */ FileInfo->Stream = LQT_MakeInput(db, FileInfo); if (!FileInfo->Stream) { Error(E_WARN|E_SYS, "couldn't open input filter for %s -- not indexed", FileInfo->Name ); LQT_DestroyFileInfo(db, FileInfo); return (t_FileInfo *) 0; } return FileInfo; }