mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1152 lines
23 KiB
1152 lines
23 KiB
/*** srdaem.c - symbol database daemon
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#include <windows.h>
|
|
#include <tools.h>
|
|
|
|
#include "db.h"
|
|
#include "symref.h"
|
|
#include "symmsg.h"
|
|
|
|
PSZ database = NULL;
|
|
|
|
long sectotal = 1L; /* amount of time spent in indexing */
|
|
long cchtotal = 0L; /* total amount of indexed text */
|
|
|
|
#define TIMED(a) \
|
|
{ time_t tmBegin, tmEnd; \
|
|
long cch; \
|
|
\
|
|
tmBegin = tmNow (); \
|
|
cch = a; \
|
|
tmEnd = tmNow (); \
|
|
if (cch != 0) { \
|
|
sectotal += tmEnd - tmBegin; \
|
|
cchtotal += cch; \
|
|
} \
|
|
}
|
|
|
|
|
|
/* Forward definitions
|
|
*/
|
|
time_t tmNow (void);
|
|
|
|
void NewDatabase (HANDLE h, PSZ apsz[]);
|
|
void AddDirectory (HANDLE h, PSZ apsz[]);
|
|
void ModifyFile (HANDLE h, PSZ apsz[]);
|
|
void Synchronize (HANDLE h, PSZ apsz[]);
|
|
void AddExtention (HANDLE h, PSZ apsz[]);
|
|
void AddNoise (HANDLE h, PSZ apsz[]);
|
|
void Shutdown (HANDLE h, PSZ apsz[]);
|
|
void Locate (HANDLE h, PSZ apsz[]);
|
|
void Flush (HANDLE h, PSZ apsz[]);
|
|
|
|
struct {
|
|
char *szcmd; /* command text */
|
|
void (*pfn) (HANDLE h, PSZ apsz[]); /* function to process text */
|
|
} fnTable[] =
|
|
{ { CMD_SET_DATABASE, NewDatabase },
|
|
{ CMD_ADD_DIRECTORY, AddDirectory },
|
|
{ CMD_MODIFY_FILE, ModifyFile },
|
|
{ CMD_SYNCHRONIZE, Synchronize },
|
|
{ CMD_ADD_EXTENTION, AddExtention },
|
|
{ CMD_ADD_NOISE_WORD, AddNoise },
|
|
{ CMD_SHUTDOWN, Shutdown },
|
|
{ CMD_LOCATE, Locate },
|
|
{ CMD_FLUSH, Flush },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
time_t tmNow (void)
|
|
{
|
|
time_t tm;
|
|
|
|
time (&tm);
|
|
return tm;
|
|
}
|
|
|
|
typedef struct ChildData {
|
|
time_t tmSyncDelta, tmFlushDelta;
|
|
} CHILDDATA, *PCHILDDATA;
|
|
|
|
/* SRChildThread - child thread that generates time-based events
|
|
*
|
|
* pcd pointer to child data
|
|
*/
|
|
|
|
void SRChildThread (PCHILDDATA pcd)
|
|
{
|
|
time_t tmSyncNext, tmFlushNext, tmSleep;
|
|
char buf[CBMSG];
|
|
long cbRead;
|
|
|
|
tmSyncNext = tmNow () + pcd->tmSyncDelta;
|
|
tmFlushNext = tmNow () + pcd->tmFlushDelta;
|
|
|
|
while (TRUE) {
|
|
|
|
//
|
|
// Sleep until next event
|
|
//
|
|
|
|
tmSleep = min (tmSyncNext, tmFlushNext) - tmNow ();
|
|
if (tmSleep >= 0)
|
|
Sleep (tmSleep * 1000);
|
|
|
|
//
|
|
// Dispatch to relevant event
|
|
//
|
|
|
|
if (tmNow () >= tmSyncNext) {
|
|
CallNamedPipe (PSZPIPE,
|
|
CMD_SYNCHRONIZE,
|
|
strlen (CMD_SYNCHRONIZE) + 1,
|
|
buf,
|
|
CBMSG,
|
|
&cbRead,
|
|
NMPWAIT_WAIT_FOREVER);
|
|
tmSyncNext = tmNow () + pcd->tmSyncDelta;
|
|
}
|
|
|
|
if (tmNow () >= tmFlushNext) {
|
|
CallNamedPipe (PSZPIPE,
|
|
CMD_FLUSH,
|
|
strlen (CMD_FLUSH) + 1,
|
|
buf,
|
|
CBMSG,
|
|
&cbRead,
|
|
NMPWAIT_WAIT_FOREVER);
|
|
tmFlushNext = tmNow () + pcd->tmFlushDelta;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void Usage (void)
|
|
{
|
|
printf ("Usage: srdaem -daemon [-f n] [-s n] [database]\n");
|
|
printf (" run as daemon\n");
|
|
printf (" srdaem -D[sShrnifde] [database] dump database\n");
|
|
printf (" s display all symbol text\n");
|
|
printf (" S display all symbol information\n");
|
|
printf (" h display hash bucket #\n");
|
|
printf (" r display detailed references\n");
|
|
|
|
printf (" n display data symbol text\n");
|
|
printf (" i display ignored symbol text\n");
|
|
printf (" f display file name text\n");
|
|
printf (" d display directory root text\n");
|
|
printf (" e display skipped extension text\n");
|
|
|
|
printf (" srdaem - [database] read command from stdin\n");
|
|
printf (" srdaem -c [database] create database stdin\n");
|
|
}
|
|
|
|
|
|
/* SRProcessCommand - process one database command
|
|
*
|
|
* h handle for responses
|
|
* psz command including all data
|
|
*/
|
|
void SRProcessCommand (HANDLE h, PSZ psz)
|
|
{
|
|
PSZ apsz[5];
|
|
int i;
|
|
|
|
/* Parse off all space-separated fields
|
|
*/
|
|
apsz[i = 0] = strtok (psz, " \t");
|
|
while (apsz[i++] != NULL)
|
|
apsz[i] = strtok (NULL, " \t");
|
|
|
|
/* dispatch to function based upon first token
|
|
*/
|
|
for (i = 0; fnTable[i].szcmd != NULL; i++)
|
|
if (!strcmp (apsz[0], fnTable[i].szcmd)) {
|
|
(*fnTable[i].pfn) (h, apsz + 1);
|
|
return;
|
|
}
|
|
printf ("Unknown command: %s\n", apsz[0]);
|
|
}
|
|
|
|
/* SRDaemon - be a pipe daemon and answer SYMREF requests
|
|
*/
|
|
void SRDaemon (int c, char *v[])
|
|
{
|
|
CHILDDATA cd;
|
|
HANDLE hPipe;
|
|
HANDLE hChild;
|
|
DWORD tidChild;
|
|
char buf[CBMSG];
|
|
long cbRead;
|
|
|
|
//
|
|
// Parse commands
|
|
//
|
|
|
|
cd.tmSyncDelta = 60 * 60;
|
|
cd.tmFlushDelta = 1 * 60;
|
|
|
|
while (c) {
|
|
if (c >= 2 && !strcmp (*v, "-s")) {
|
|
SHIFT (c, v);
|
|
cd.tmSyncDelta = atoi (*v);
|
|
}
|
|
else
|
|
if (c >= 2 && !strcmp (*v, "-f")) {
|
|
SHIFT (c, v);
|
|
cd.tmFlushDelta = atoi (*v);
|
|
}
|
|
else
|
|
if (c == 1) {
|
|
if (database != NULL)
|
|
free (database);
|
|
database = _strdup (*v);
|
|
}
|
|
else {
|
|
Usage ();
|
|
exit (1);
|
|
}
|
|
SHIFT (c, v);
|
|
}
|
|
//
|
|
// Create named pipe
|
|
//
|
|
|
|
hPipe = CreateNamedPipe (PSZPIPE,
|
|
PIPE_ACCESS_DUPLEX,
|
|
(PIPE_WAIT | PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE),
|
|
PIPE_UNLIMITED_INSTANCES,
|
|
100 * CBMSG,
|
|
5 * CBMSG,
|
|
5 * 1000, // ???
|
|
NULL);
|
|
|
|
if (hPipe == HANDLE_BAD) {
|
|
NOTEERROR ("SRDaemon: CreateNamedPipe");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Start sync/flush thread
|
|
//
|
|
|
|
hChild = CreateThread (NULL,
|
|
100,
|
|
(LPTHREAD_START_ROUTINE)SRChildThread,
|
|
(LPVOID) &cd,
|
|
0,
|
|
&tidChild);
|
|
|
|
if (hChild == (HANDLE)0) {
|
|
NOTEERROR ("SRDaemon: CreateThread");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Open database
|
|
//
|
|
|
|
if (!SROpen (database))
|
|
printf ("SRDaemon: SROpen unable to open database %s\n", database);
|
|
else {
|
|
|
|
//
|
|
// Main loop processing events from pipe
|
|
//
|
|
|
|
while (TRUE) {
|
|
if (!ConnectNamedPipe (hPipe, NULL)) {
|
|
NOTEERROR ("SRDaemon: ConnectNamedPipe");
|
|
break;
|
|
}
|
|
|
|
if (!ReadFile (hPipe, buf, CBMSG, &cbRead, NULL)) {
|
|
NOTEERROR ("SRDaemon: ReadFile");
|
|
break;
|
|
}
|
|
|
|
SRProcessCommand (hPipe, buf);
|
|
|
|
FlushFileBuffers (hPipe);
|
|
|
|
if (!DisconnectNamedPipe (hPipe)) {
|
|
NOTEERROR ("SRDaemon: DisconnectNamedPipe");
|
|
break;
|
|
}
|
|
}
|
|
|
|
SRClose (fDirty);
|
|
|
|
}
|
|
|
|
CloseHandle (hPipe);
|
|
|
|
}
|
|
|
|
/* fnSend - applied function for sending strings
|
|
*
|
|
* h handle for reply
|
|
* psz string to reply
|
|
*/
|
|
BOOL fnSend (HANDLE h, PSZ psz)
|
|
{
|
|
long cbWritten;
|
|
|
|
if (psz == NULL)
|
|
psz = RSP_EOD;
|
|
|
|
if (h == HANDLE_BAD) {
|
|
printf ("%s\n", psz);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return WriteFile (h, psz, strlen (psz) + 1, &cbWritten, NULL);
|
|
}
|
|
|
|
/* NewDatabase - change to a new database
|
|
*
|
|
* apsz pointer to array of nul-terminated strings
|
|
* apsz[0] is the name of the new database
|
|
*/
|
|
void NewDatabase (HANDLE h, PSZ apsz[])
|
|
{
|
|
h;
|
|
|
|
SRClose (fDirty);
|
|
|
|
if (!SROpen (apsz[0])) {
|
|
printf ("NewDatabase: SROpen unable to open database %s\n", apsz[0]);
|
|
exit (1);
|
|
}
|
|
free (database);
|
|
database = _strdup (apsz[0]);
|
|
fDirty = FALSE;
|
|
printf ("New database is %s\n", database);
|
|
}
|
|
|
|
/* Shutdown - commit and close database
|
|
*
|
|
* apsz pointer to array of nul-terminated strings
|
|
*/
|
|
void Shutdown (HANDLE h, PSZ apsz[])
|
|
{
|
|
SRClose (fDirty);
|
|
fnSend (h, "Shutdown complete");
|
|
exit (1);
|
|
|
|
apsz;
|
|
}
|
|
|
|
/* Locate - find symbol in database and files
|
|
*
|
|
* apsz pointer to array of nul-terminated strings
|
|
* apsz[0] is the symbol
|
|
* apsz[1] [optiona] is the root scope for matching files
|
|
*/
|
|
void Locate (HANDLE h, PSZ apsz[])
|
|
{
|
|
_strlwr (apsz[0]);
|
|
SRSymLocate (fnSend, h, apsz);
|
|
}
|
|
|
|
/* Flush - write out database
|
|
*
|
|
* apsz pointer to array of nul-terminated strings
|
|
*/
|
|
void Flush (HANDLE h, PSZ apsz[])
|
|
{
|
|
h;
|
|
|
|
if (fDirty) {
|
|
int hi, lo;
|
|
double rate;
|
|
|
|
DBFlush (pdbSym);
|
|
DBFlush (pdbRef);
|
|
|
|
rate = (cchtotal / 1024.0) / sectotal;
|
|
hi = (int) rate;
|
|
lo = (int) (1000.0 * (rate - hi));
|
|
|
|
printf ("Flush: %d bytes in %d seconds = %d.%03dKB/sec\n", cchtotal, sectotal, hi, lo);
|
|
}
|
|
fDirty = FALSE;
|
|
apsz;
|
|
}
|
|
|
|
|
|
/** Directory-centric maintenance of database
|
|
*
|
|
* The content database consists of a set of files. These files were
|
|
* found by doing tree enumerations under a set of directories.
|
|
*
|
|
* From the client standpoint, there are actions that are relevant
|
|
* to maintenance of the database:
|
|
*
|
|
* adding a directory
|
|
*
|
|
* if (directory in database)
|
|
* do nothing
|
|
* else
|
|
* add directory to database
|
|
* for (each file recursively under directory)
|
|
* if (file is indexable)
|
|
* if (file is not in database)
|
|
* index file
|
|
*
|
|
* modifying a file
|
|
* if (file is not indexable)
|
|
* do nothing
|
|
* else
|
|
* if (file is in database)
|
|
* remove file
|
|
* index file
|
|
* else
|
|
* for (each parent of file)
|
|
* if (parent is in database)
|
|
* index file
|
|
*
|
|
*
|
|
* synchronizing the database
|
|
*
|
|
* This is done to check for files that have been added/deleted/
|
|
* changed without the database knowing it. It occurs in two
|
|
* passes.
|
|
*
|
|
* Pass1 looks for files that have been updated or deleted
|
|
* for (each file in database)
|
|
* if (file not present on disk)
|
|
* remove file
|
|
* else
|
|
* if (file not indexable)
|
|
* remove file
|
|
* else
|
|
* if (file on disk is newer than file in database)
|
|
* remove file
|
|
* index file
|
|
*
|
|
* Pass2 finds new file
|
|
* for (each directory in database)
|
|
* for (each file recursively under directory)
|
|
* if (file is indexable)
|
|
* if (file is not in database)
|
|
* index file
|
|
*
|
|
* adding a new extention to the don't index list
|
|
* if (extention is not ignored)
|
|
* add extention
|
|
* for (each file in database)
|
|
* if (file is not indexable)
|
|
* remove file
|
|
*
|
|
* adding a new noise word
|
|
* if (word is in database)
|
|
* for (each reference to word)
|
|
* remove reference from it's file
|
|
* remove word
|
|
* add noise word
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/* fIndexable - see if extension indicates an indexable file
|
|
*
|
|
* We use a table of known non-indexable extensions to filter file
|
|
* name.
|
|
*
|
|
* pszName name of file
|
|
*
|
|
* returns TRUE if file can be indexed
|
|
*/
|
|
BOOL fIndexable (PSZ pszName)
|
|
{
|
|
char szExt[MAX_PATH];
|
|
|
|
//
|
|
// See if its extension indicates we shouldn't index it
|
|
//
|
|
|
|
extention (pszName, szExt);
|
|
_strlwr (szExt);
|
|
return pextFind (szExt, NULL, FALSE) == NULL;
|
|
}
|
|
|
|
|
|
void WalkEnum (char *szFile, FIND *pfbuf, void *pData);
|
|
|
|
/* WalkDir - look for indexable files that aren't in the database and
|
|
* index them
|
|
*
|
|
* psz text of directory
|
|
*/
|
|
|
|
void WalkDir (PSZ psz)
|
|
{
|
|
char dirname[MAX_PATH];
|
|
|
|
strcpy (dirname, psz);
|
|
if (psz[strlen(psz)-1] != '\\')
|
|
strcat (dirname, "\\");
|
|
strcat (dirname, "*");
|
|
|
|
forfile (dirname, A_ALL, WalkEnum, NULL);
|
|
}
|
|
|
|
/* WalkEnum - enumerator for adding new files to database
|
|
*
|
|
* szFile pointer to file name
|
|
* pfbuf find buf giving stat information
|
|
* pData additional data (ignored)
|
|
*/
|
|
|
|
void WalkEnum (char *szFile, FIND *pfbuf, void *pData)
|
|
{
|
|
//
|
|
// if we're looking at . or .. or deleted skip them
|
|
//
|
|
|
|
if (!strcmp (pfbuf->fbuf.cFileName, ".") ||
|
|
!strcmp (pfbuf->fbuf.cFileName, "..") ||
|
|
!_strcmpi (pfbuf->fbuf.cFileName, "deleted"))
|
|
;
|
|
|
|
//
|
|
// if we're looking at a directory go and enumerate through it
|
|
//
|
|
|
|
else
|
|
if ((pfbuf->fbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
|
WalkDir (szFile);
|
|
|
|
//
|
|
// if file is indexable not in database go and add it
|
|
//
|
|
|
|
else
|
|
if (fIndexable (szFile) && pfilFind (szFile, NULL, FALSE) == NULL) {
|
|
|
|
printf ("WalkEnum: Adding %s\n", szFile);
|
|
|
|
TIMED (IndexFile (HANDLE_BAD, szFile));
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
}
|
|
|
|
pData;
|
|
}
|
|
|
|
|
|
/* AddDirectory - add a directory to the database
|
|
*
|
|
* h HANDLE to response pipe
|
|
* apsz[] array of additional data.
|
|
* apsz[0] is name of directory
|
|
*/
|
|
|
|
void AddDirectory (HANDLE h, PSZ apsz[])
|
|
{
|
|
|
|
h;
|
|
|
|
//
|
|
// if directory not in database
|
|
//
|
|
|
|
if (pdirFind (apsz[0], NULL, FALSE) == NULL) {
|
|
|
|
printf ("AddDirectory: adding %s\n", apsz[0]);
|
|
|
|
//
|
|
// Add directory to database
|
|
//
|
|
|
|
pdirFind (apsz[0], NULL, TRUE);
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
|
|
//
|
|
// enumerate all files and add indexable ones to database
|
|
//
|
|
|
|
WalkDir (apsz[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* ModifyFile - note that a file has been changed
|
|
*
|
|
* h HANDLE to response pipe
|
|
* apsz[] array of additional data
|
|
* apsz[0] is name of directory
|
|
*/
|
|
|
|
void ModifyFile (HANDLE h, PSZ apsz[])
|
|
{
|
|
h;
|
|
|
|
//
|
|
// if file is not indexable, do nothing
|
|
//
|
|
|
|
if (!fIndexable (apsz[0]))
|
|
;
|
|
|
|
//
|
|
// if file is in database already
|
|
//
|
|
|
|
else
|
|
if (pfilFind (apsz[0], NULL, FALSE) != NULL) {
|
|
|
|
printf ("ModifyFile: Updating %s\n", apsz[0]);
|
|
|
|
//
|
|
// remove file from database
|
|
//
|
|
|
|
RemoveFile (apsz[0]);
|
|
|
|
//
|
|
// reindex file
|
|
//
|
|
|
|
TIMED (IndexFile (HANDLE_BAD, apsz[0]));
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
|
|
}
|
|
|
|
//
|
|
// for each parent of file
|
|
//
|
|
|
|
else {
|
|
char *p;
|
|
BOOL fInDB;
|
|
|
|
p = apsz[0];
|
|
|
|
while (*p != '\0') {
|
|
*p = '\0';
|
|
|
|
//
|
|
// if parent is in database
|
|
//
|
|
|
|
fInDB = pdirFind (apsz[0], NULL, FALSE) != NULL;
|
|
|
|
*p = '\\';
|
|
|
|
if (fInDB) {
|
|
|
|
printf ("ModifyFile: Adding %s\n", apsz[0]);
|
|
|
|
//
|
|
// index file
|
|
//
|
|
|
|
TIMED (IndexFile (HANDLE_BAD, apsz[0]));
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
|
|
break;
|
|
}
|
|
|
|
p = strbscan (p + 1, "\\");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* EnSyncDir - tree walk a directory looking for new files
|
|
*
|
|
* h hash value being examined
|
|
* osh offset of symhdr of dir
|
|
* psh pointer to symhdr of dir
|
|
* pv pointer to asciiz string for switch arguments
|
|
*/
|
|
|
|
void EnSyncDir (HASH h, OFFSET osh, PSH psh, void * pv)
|
|
{
|
|
h; osh; pv;
|
|
|
|
|
|
WalkDir (SZ (psh));
|
|
}
|
|
|
|
|
|
/* EnSyncFile - check to see if a file has been updated or deleted
|
|
*
|
|
* h hash value being examined
|
|
* osh offset of symhdr of file
|
|
* psh pointer to symhdr of file
|
|
* pv pointer to asciiz string for switch arguments
|
|
*/
|
|
void EnSyncFile (HASH h, OFFSET osh, PSH psh, void * pv)
|
|
{
|
|
|
|
PFIL pfil = (PFIL) psh;
|
|
HANDLE hf;
|
|
char szFile[MAX_PATH];
|
|
|
|
h; osh; pv;
|
|
|
|
|
|
//
|
|
// Get copy of file name since we might delete file record
|
|
//
|
|
|
|
strcpy (szFile, pfil->name.sz);
|
|
|
|
//
|
|
// Open file to see if it exists
|
|
//
|
|
|
|
hf = CreateFile (szFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if (hf == HANDLE_BAD) {
|
|
|
|
printf ("EnSyncFile: getting rid of nonexistent %s\n", szFile);
|
|
|
|
//
|
|
// since we cannot open file, it's likely symref can't either
|
|
// we remove the file from the database. If this is transitory,
|
|
// we can always add it in later during pass II
|
|
//
|
|
|
|
RemoveFile (szFile);
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
|
|
}
|
|
//
|
|
// if the file is not indexable we should remove it
|
|
//
|
|
|
|
else {
|
|
FILETIME tm;
|
|
|
|
//
|
|
// retrieve the last-modified time
|
|
//
|
|
|
|
GetFileTime (hf, NULL, NULL, &tm);
|
|
|
|
if (!fIndexable (szFile)) {
|
|
|
|
printf ("EnSyncFile: getting rid of unindexable %s\n", szFile);
|
|
|
|
RemoveFile (szFile);
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
}
|
|
|
|
//
|
|
// if the file has changed from the database, remove it and index it
|
|
//
|
|
|
|
else
|
|
if (pfil->tmMod.dwLowDateTime != tm.dwLowDateTime ||
|
|
pfil->tmMod.dwHighDateTime != tm.dwHighDateTime) {
|
|
|
|
printf ("EnSyncFile: updating %s\n", szFile);
|
|
|
|
RemoveFile (szFile);
|
|
|
|
TIMED (IndexFile (hf, szFile));
|
|
|
|
hf = HANDLE_BAD;
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// release the file handle
|
|
//
|
|
|
|
if (hf != HANDLE_BAD)
|
|
CloseHandle (hf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Synchronize - synchronizing the database
|
|
*
|
|
* h HANDLE to response pipe
|
|
* apsz[] array of additional data ignored
|
|
*/
|
|
|
|
void Synchronize (HANDLE h, PSZ apsz[])
|
|
{
|
|
h; apsz;
|
|
|
|
//
|
|
// for each file in database, sync it with disk
|
|
//
|
|
|
|
EnSym (EnSyncFile, NULL, TY_FIL);
|
|
|
|
//
|
|
// for each dir in database, tree walk it looking for new files
|
|
//
|
|
|
|
EnSym (EnSyncDir, NULL, TY_DIR);
|
|
|
|
}
|
|
|
|
|
|
/* EnAddExt - test to see if a file is ignored
|
|
*
|
|
* h hash value being examined
|
|
* osh offset of symhdr of file
|
|
* psh pointer to symhdr of file
|
|
* pv pointer to asciiz string for switch arguments
|
|
*/
|
|
void EnAddExt (HASH h, OFFSET osh, PSH psh, void * pv)
|
|
{
|
|
PFIL pfil = (PFIL) psh;
|
|
|
|
h; osh; pv;
|
|
|
|
//
|
|
// if the file is ignored then remove it
|
|
//
|
|
|
|
if (!fIndexable (pfil->name.sz))
|
|
RemoveFile (pfil->name.sz);
|
|
}
|
|
|
|
|
|
|
|
/* AddExtention - add extention to don't-index list
|
|
*
|
|
* h HANDLE to response pipe
|
|
* apsz[] array of additional data
|
|
* apsz[0] is extention to ignore
|
|
*/
|
|
|
|
void AddExtention (HANDLE h, PSZ apsz[])
|
|
{
|
|
h;
|
|
|
|
//
|
|
// if the extention is not currently ignored
|
|
//
|
|
|
|
if (pextFind (apsz[0], NULL, FALSE) == NULL) {
|
|
|
|
printf ("AddExtention: adding %s\n", apsz[0]);
|
|
|
|
//
|
|
// add it to the ignored set
|
|
//
|
|
|
|
pextFind (apsz[0], NULL, TRUE);
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
|
|
//
|
|
// for each file in database, if it's ignored, remove it
|
|
//
|
|
|
|
EnSym (EnAddExt, NULL, TY_FIL);
|
|
|
|
}
|
|
}
|
|
|
|
/* AddNoise - add noise word
|
|
*
|
|
* h HANDLE to response pipe
|
|
* apsz[] array of additional data
|
|
* apsz[0] is new noise word
|
|
*/
|
|
|
|
void AddNoise (HANDLE h, PSZ apsz[])
|
|
{
|
|
h;
|
|
|
|
//
|
|
// if word is currently in database
|
|
//
|
|
|
|
if (psymFind (apsz[0], NULL, FALSE)) {
|
|
|
|
printf ("AddNoise: removing valid symbol %s\n", apsz[0]);
|
|
|
|
//
|
|
// Remove symbol from database
|
|
//
|
|
|
|
RemoveSym (apsz[0]);
|
|
|
|
}
|
|
|
|
//
|
|
// add noise word
|
|
//
|
|
|
|
pnoiFind (apsz[0], NULL, TRUE);
|
|
|
|
//
|
|
// Make sure that the database gets written out soon
|
|
//
|
|
|
|
fDirty = TRUE;
|
|
}
|
|
|
|
|
|
/* Debugging dump values
|
|
*/
|
|
|
|
HASH ohash;
|
|
long csym, cfil, cref, cvec, ccol, ccolmax, ccolcur;
|
|
|
|
/* EnDump - dump function called by symbol enumerator
|
|
*
|
|
* h hash value being examined
|
|
* osh offset of symhdr
|
|
* psh pointer to symhdr
|
|
* pv pointer to asciiz string for switch arguments
|
|
*/
|
|
void EnDump (HASH h, OFFSET osh, PSH psh, void * pv)
|
|
{
|
|
#define psz ((PSZ)pv)
|
|
#define psym ((PSYM)psh)
|
|
#define pfil ((PFIL)psh)
|
|
|
|
OFFSET oref;
|
|
PREF pref;
|
|
int i;
|
|
|
|
if (h != ohash) {
|
|
if (strchr (psz, 'h') != NULL)
|
|
printf ("HASH[%x] = %08x\n", h, osh);
|
|
ohash = h;
|
|
ccolmax = max (ccolmax, ccolcur);
|
|
ccolcur = 0;
|
|
}
|
|
else {
|
|
ccol++;
|
|
ccolcur++;
|
|
}
|
|
|
|
if (psh->type == TY_FIL)
|
|
cfil++;
|
|
else
|
|
csym++;
|
|
|
|
//
|
|
// Check for printing the symbol text. Do so if
|
|
// 'n' and it is a data symbol
|
|
// 'i' and it is an ignored symbol
|
|
// 'f' and it is a file symbol
|
|
// 'd' and it is a dir symbol
|
|
// 's' (do all symbols)
|
|
//
|
|
|
|
if ((strchr (psz, 'n') != NULL && psh->type == TY_SYM) ||
|
|
(strchr (psz, 'i') != NULL && psh->type == TY_NOI) ||
|
|
(strchr (psz, 'f') != NULL && psh->type == TY_FIL) ||
|
|
(strchr (psz, 'd') != NULL && psh->type == TY_DIR) ||
|
|
(strchr (psz, 'e') != NULL && psh->type == TY_EXT) ||
|
|
strchr (psz, 's') != NULL)
|
|
printf ("%s\n", SZ(psh));
|
|
|
|
//
|
|
// Check for printing symbol records
|
|
//
|
|
if (strchr (psz, 'S') != NULL) {
|
|
printf ("%08x: type:%02x oshNext:%08x", osh, psh->type, psh->oshNext);
|
|
|
|
if (psh->type == TY_SYM)
|
|
printf ("\n oref:%08x sz:%s\n", psym->oref, psym->name.sz);
|
|
else
|
|
if (psh->type == TY_FIL) {
|
|
printf (" oref:%08x ompBlkLine:%08x\n cblk:%04x sz:%s",
|
|
pfil->oref, pfil->ompBlkLine, pfil->cblk,
|
|
pfil->name.sz);
|
|
}
|
|
else
|
|
printf (" sz:%s\n", SZ(psh));
|
|
}
|
|
|
|
if (psh->type == TY_FIL) {
|
|
if (pfil->ompBlkLine != (OFFSET)0)
|
|
cvec++;
|
|
}
|
|
else
|
|
if (psh->type == TY_SYM) {
|
|
oref = psym->oref;
|
|
while (oref != (OFFSET)0) {
|
|
PFIL pfilTmp;
|
|
|
|
cref++;
|
|
pref = MAPREFERENCE (oref);
|
|
pfilTmp = MAPFIL (pref->ofil);
|
|
|
|
//
|
|
// Check for printing out all references
|
|
//
|
|
|
|
if (strchr (psz, 'r') != NULL) {
|
|
printf ("%08x: orefNext:%08x ofil:%08x osym:%08x\n orefFileNext:%08x ",
|
|
oref, pref->orefNext, pref->ofil,
|
|
pref->osym, pref->orefFileNext);
|
|
|
|
for (i = 0; i < pfilTmp->cblk; i++)
|
|
printf ("%c", "01"[(pref->bm[i>>3] & (1 << (i & 7))) != 0]);
|
|
printf ("\n");
|
|
}
|
|
oref = pref->orefNext;
|
|
}
|
|
}
|
|
#undef psz
|
|
#undef psym
|
|
#undef pfil
|
|
}
|
|
|
|
/* SRDump - debgging dump of database
|
|
*
|
|
* psz pointer to switch
|
|
*/
|
|
void SRDump (PSZ psz)
|
|
{
|
|
cfil = 0;
|
|
csym = 0;
|
|
cref = 0;
|
|
cvec = 0;
|
|
ccol = 0;
|
|
ccolmax = 0;
|
|
ccolcur = 0;
|
|
ohash = -1;
|
|
EnSym (EnDump, psz, TY_ALL);
|
|
|
|
if (!strcmp (psz, "-D")) {
|
|
printf ("files %8d\n", cfil);
|
|
printf ("symbols %8d\n", csym);
|
|
printf ("references %8d\n", cref);
|
|
printf ("map vectors %8d\n", cvec);
|
|
printf ("collisions %8d\n", ccol);
|
|
printf ("max chain %8d\n", ccolmax);
|
|
}
|
|
}
|
|
|
|
/* main - top-level driver
|
|
*
|
|
* The acceptable syntax is:
|
|
*
|
|
* srdaem -daemon
|
|
* operate as server
|
|
*
|
|
* srdaem -Dstuff
|
|
* debugging dump of database
|
|
*
|
|
* srdaem -
|
|
* reads commands from stdin
|
|
*
|
|
*/
|
|
int main (int c, char *v[])
|
|
{
|
|
PSZ psz;
|
|
|
|
database = _strdup ("database");
|
|
|
|
SHIFT (c, v);
|
|
|
|
if (c >= 1)
|
|
if (!strcmp (*v, "-daemon")) {
|
|
SHIFT (c, v);
|
|
SRDaemon (c, v);
|
|
}
|
|
else {
|
|
if (c == 2) {
|
|
free (database);
|
|
database = _strdup (v[1]);
|
|
c--;
|
|
}
|
|
if (c == 1)
|
|
if (!strncmp (*v, "-D", 2)) {
|
|
if (!SROpen (database)) {
|
|
printf ("Cannot open %s\n", database);
|
|
return 1;
|
|
}
|
|
SRDump (*v);
|
|
SRClose (fDirty);
|
|
return 0;
|
|
}
|
|
else
|
|
if (!strcmp (*v, "-")) {
|
|
if (!SROpen (database)) {
|
|
printf ("Cannot open %s\n", database);
|
|
return 1;
|
|
}
|
|
psz = (PSZ ) malloc (CBMSG);
|
|
while (fgetl (psz, MAX_PATH, stdin))
|
|
SRProcessCommand (HANDLE_BAD, psz);
|
|
free (psz);
|
|
return 0;
|
|
}
|
|
else
|
|
if (!strcmp (*v, "-c")) {
|
|
if (!SRCreate (database)) {
|
|
printf ("Cannot create %s\n", database);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Usage ();
|
|
return 1;
|
|
}
|