/* fileindex.c -- Copyright 1989, 1990, 1993, 1994 Liam R. Quin. * All Rights Reserved. * This code is NOT in the public domain. * See the file COPYRIGHT for full details. * * A simple program to give information about one or more files about * which information is stored in the lq-text database. */ static char *Revision = "@(#) $Id: lqfile.c,v 1.16 2001/05/31 03:50:13 liam Exp $"; #include "globals.h" /* defines and declarations for database filenames */ #include "error.h" #include #include #include #ifdef HAVE_FCNTL_H # include /* for O_RDONLY etc */ #endif #ifdef HAVE_STDLIB_H # include #else # include #endif #ifdef HAVE_UNISTD_H # include #endif #include "emalloc.h" #include "fileinfo.h" #include "lqutil.h" #include "liblqtext.h" char *progname; /** System calls and library functions used in this file: **/ /** Unix System calls: **/ /** System Library Functions: **/ /** Functions defined within this file: **/ PRIVATE void AddInfo( #ifdef HAVE_PROTO t_LQTEXT_Database *db, char *FileName #endif ); PRIVATE void AllInfo( #ifdef HAVE_PROTO t_LQTEXT_Database *db #endif ); PRIVATE void DisplayFileInfo( #ifdef HAVE_PROTO t_LQTEXT_Database *db, t_FileInfo *FileInfo #endif ); PRIVATE void PrintFIDInfo( #ifdef HAVE_PROTO t_LQTEXT_Database *db, t_FID FID #endif ); PRIVATE void PrintInfo( #ifdef HAVE_PROTO t_LQTEXT_Database *db, char *Name #endif ); int AllFiles = 0; int ListMode = 0; int AddFiles = 0; int UseMatchFormatForList = 0; int main(argc, argv) int argc; char *argv[]; { extern int optind, getopt(); /** extern char *optarg; (unused at the moment) **/ int ch; int ErrorFlag = 0; int FIDMode = 0; t_lqdbOptions *Options; t_LQTEXT_Database *db; progname = argv[0]; Options = LQT_InitFromArgv(argc, argv); /* All programs take Zz:Vv */ while ((ch = getopt(argc, argv, "Zz:VvAaFlMx")) != EOF) { switch (ch) { case 'z': case 'Z': break; /* done by LQT_InitFromArgv(); */ case 'V': fprintf(stderr, "%s version %s\n", progname, Revision); break; case 'F': FIDMode = 1; break; case 'A': AddFiles = 1; break; case 'a': AllFiles = 1; break; case 'l': ListMode = 1; break; case 'M': ListMode = 1; UseMatchFormatForList = 1; break; case 'x': ErrorFlag = (-1); break; case '?': ErrorFlag = 1; break; } } /* Normally put call to lrqError here to give a helpful message, * but not yet ready to ship the error handling package, sorry */ if (ErrorFlag) { fprintf(stderr, "%s: usage: %s [options] [files]\n",progname,progname); fprintf(stderr, "%s: options are:\n", progname); LQT_PrintDefaultUsage(Options); fputs("\ -F -- treat file names as numeric FIDs instead\n\ -l -- list mode: no header output or lines drawn\n\ -M -- list mode output is in match format (implies -l)\n\ -t N -- set trace level to N [default: 0]\n\ -x -- print this explanation\n\ \n\ In addition, if no files are given, the following are understood:\n\ -A -- add the named files to the list of known files\n\ -a -- list information about all files\n", stderr); exit((ErrorFlag > 0) ? 1 : 0); } db = LQT_OpenDatabase(Options, O_RDONLY, 0); if (!db || LQT_ObtainReadOnlyAccess(db) < 0) { Error(E_FATAL, "couldn't open lq-text database in directory \"%s\"", db->DatabaseDirectory ); } if (AllFiles && AddFiles) { fprintf(stderr, "%s: do not use both -a and -A options\n", progname); fprintf(stderr, "\tuse %s -x for further explanation.\n", progname); exit(1); } if (optind >= argc && !AllFiles && !AddFiles) { Error(E_USAGE|E_FATAL|E_XHINT, "You must either give the -a option or specify files to list" ); } if (!AddFiles && !ListMode) { printf("%-7.7s | FileType | %-20.20s | %s\n", "FID", "Date Last indexed", "Current Location"); puts( "========|==========|======================|===================================" ); } if (AllFiles) { AllInfo(db); } else { if (AddFiles) { LQT_ObtainWriteAccess(db); } while (optind < argc) { if (AddFiles) { AddInfo(db, argv[optind++]); } else { if (FIDMode) { t_FID FID; if ((FID = atol(argv[optind])) == (t_FID) 0) { Error(E_WARN, "Invalid FID %s; FIDs must be numeric, > 0L", argv[optind] ); } else { PrintFIDInfo(db, FID); } } else { PrintInfo(db, argv[optind]); } ++optind; } } } LQT_SyncAndCloseAllKeyValueDatabases(db); exit(0); /*NOTREACHED*/ return 1; /* for lint and gcc... */ } PRIVATE void PrintInfo(db, Name) t_LQTEXT_Database *db; char *Name; { t_FID FID; if ((FID = LQT_NameToFID(db, Name)) == (t_FID) 0) { Error(E_WARN, "No FID available for filename: %s", Name ); } else { PrintFIDInfo(db, FID); } } PRIVATE void PrintFIDInfo(db, FID) t_LQTEXT_Database *db; t_FID FID; { t_FileInfo *FileInfo; /* get info from the list */ if ((FileInfo = LQT_FIDToFileInfo(db, FID)) == (t_FileInfo *) 0) { Error(E_WARN, "No Index information for FID: %ld", FID ); } else { DisplayFileInfo(db, FileInfo); } } PRIVATE void DisplayFileInfo(db, theFileInfo) t_LQTEXT_Database *db; t_FileInfo *theFileInfo; { extern char *ctime(); char *DateString; register char *p; DateString = ctime(&(theFileInfo->Date)); /* The string returned by ctime usually ends in a newline, * which we don't want. So we'll remove it: */ for (p = DateString; *p; p++) { if (*p == '\n' || *p == '\r') { *p = '\0'; break; } } if (ListMode) { if (UseMatchFormatForList) { /* NumberOfWords, BlockInFile, WordInBlock, FID, DocName */ printf("0 0 0 %lu %s\n", theFileInfo->FID, theFileInfo->Name ); } else { printf("%lu\t%s\t%s\t%s\n", theFileInfo->FID, LQT_GetFilterName(db, theFileInfo), &DateString[4], theFileInfo->Name ); } } else { printf("%5lu | %10.10s | %-20.20s | %s\n", theFileInfo->FID, LQT_GetFilterName(db, theFileInfo), &DateString[4], theFileInfo->Name ); } } /** Mon Sep 25 23:58:53 BST 1989 FID | FileType | Date Last indexed | Current Location ========|==========|======================|==================================== 1 | plain | Sep 25 20:31:26 1989 | /usr2/liam/Bible/NT/John/john01.kjv 2 | netnews | Sep 25 20:31:28 1989 | alt/lifestyle/barefoot/1064 3 | SGML | Sep 25 20:31:30 1989 | /usr2/liam/Bible/NT/John/john03.kjv **/ PRIVATE void AllInfo(db) t_LQTEXT_Database *db; { t_FileInfo *FileInfo; long FID; long MaxFid = LQT_GetMaxFID(db); for (FID = 0L; FID <= MaxFid; FID++) { if ((FileInfo = LQT_FIDToFileInfo(db, FID)) != (t_FileInfo *) 0) { DisplayFileInfo(db, FileInfo); efree((char *) FileInfo); /* NOTDONE use LQT_DestroyFileInfo */ } } if (!ListMode) { printf("Max File Identifier is %lu\n", MaxFid); } } PRIVATE void AddInfo(db, FileName) t_LQTEXT_Database *db; char *FileName; { extern time_t time(); t_FileInfo FileInfo; struct stat statBuf; FileInfo.Name = FileName; (void) time(&(FileInfo.Date)); FileInfo.FID = LQT_GetMaxOrAllocateFID(db, 1); /* 1 = write current */ FileInfo.Stream = 0; if (stat(FileName, &statBuf) < 0) { Error(E_WARN|E_SYS, "Couldn't find file \"%s\" to add it's name to the index", FileName ); return; } /* determine filter type */ FileInfo.FilterType = LQT_GetFilterType(db, &FileInfo, &statBuf); printf("%ld %s (type %d, %s) -- %s\n", FileInfo.FID, FileInfo.Name, FileInfo.FilterType, LQT_GetFilterName(db, &FileInfo), LQT_SaveFileInfo(db, &FileInfo) == 0 ? "Marked as having been indexed." : "Failed to mark file as having been indexed." ); }