/* test if the whitespace of the token contains at least 2 * linebreaks. This means that this token is at the beginning of a new * paragraph */ s_bool s_test_whitespace_double_line_breaks(const char *token_whitespace, s_erc *error) { const char *forward_linebreak; const char *reverse_linebreak; S_CLR_ERR(error); forward_linebreak = s_strchr(token_whitespace, '\n', error); if (S_CHK_ERR(error, S_CONTERR, "s_test_whitespace_double_line_breaks", "Call to \"s_strchr\" failed")) return FALSE; if (forward_linebreak == NULL) /* no linebreaks */ return FALSE; reverse_linebreak = s_strrchr(token_whitespace, '\n', error); if (S_CHK_ERR(error, S_CONTERR, "s_test_whitespace_double_line_breaks", "Call to \"s_strrchr\" failed")) return FALSE; if (forward_linebreak != reverse_linebreak) /* at least 2 linebreaks */ return TRUE; return FALSE; }
/* * Create registry entries for installing service as an event source */ int install_event_source(const char *service_name) { HKEY regkey; char path[MAX_PATH] = EVENT_PATH; s_strcat(path, MAX_PATH, service_name); int ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, path, 0, 0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, ®key, 0); if (ret == ERROR_SUCCESS) { DWORD types_supported = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; TCHAR message_lib[MAX_PATH]; char *last_slash; GetModuleFileName(NULL, message_lib, MAX_PATH); last_slash = s_strrchr(message_lib, '\\', MAX_PATH); if (NULL != last_slash) *last_slash = '\0'; s_strcat(message_lib, MAX_PATH, "\\"); s_strcat(message_lib, MAX_PATH, MESSAGE_LIB); ret = RegSetValueEx(regkey, "EventMessageFile", 0, REG_SZ, (BYTE *) message_lib, strlen(message_lib)); if (ret == ERROR_SUCCESS) { ret = RegSetValueEx(regkey, "TypesSupported", 0, REG_DWORD, (LPBYTE) &types_supported, sizeof (types_supported)); } if (ret != ERROR_SUCCESS) // Failed to create either of the values { ret = COMMON_ERR_FAILED; } else { ret = COMMON_SUCCESS; } RegCloseKey(regkey); } return ret; }
/* * Service Main function - Called by the SCM after the service has started */ void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { gServiceHandle = RegisterServiceCtrlHandler(g_serviceName, ServiceCtrlHandler); if (gServiceHandle == 0) { logStartError("RegisterServiceCtrlHandler failed."); } else { // signal service is starting setServiceStatus(SERVICE_START_PENDING, TRUE, NO_ERROR, 3000); // create event for when service is signaled to stop g_serviceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (g_serviceStopEvent) { TCHAR szPath[MAX_PATH]; char *last_slash; GetModuleFileName(NULL, szPath, MAX_PATH); last_slash = s_strrchr(szPath, '\\', MAX_PATH); if (NULL != last_slash) *last_slash = '\0'; if (SetCurrentDirectory(szPath)) { std::vector<monitor::NvmMonitorBase *> monitors; monitor::NvmMonitorBase::getMonitors(monitors); size_t handleCount = monitors.size() + 1; // +1 to also add g_serviceStopEvent HANDLE handles[handleCount]; for (size_t i = 0; i < monitors.size(); i++) { handles[i] = CreateThread(NULL, 0, WorkerThread, (LPVOID) (monitors[i]), 0, NULL); } // In the case there are no monitor items, adding the stop event will keep the // service running until a Service Stop Event occurs. handles[handleCount - 1] = g_serviceStopEvent; // now running setServiceStatus(SERVICE_RUNNING, false, NO_ERROR, 0); // wait for all threads to end and Service Stop Event WaitForMultipleObjects(handleCount, handles, true, INFINITE); // clean up for (size_t i = 0; i < handleCount; i++) { CloseHandle(handles[i]); } monitor::NvmMonitorBase::deleteMonitors(monitors); setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0); } else { logStartError("Failed to set working directory."); setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0); } } else { logStartError("CreateEvent Failed"); setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0); } } }
/* Function: iPrsFinishDocument() Purpose: Finish the document. Parameters: pppPrsParser structure containing the various parser options we use to parse the data ppfPrsFormat file profile pointing to the various file options we use to parse the data pfIndexerFile file descriptor to which we send the structured index stream pucFilePath file path of the file currently being parsed (optional) zStartOffset start index in the file zEndOffset end index in the file uiDocumentTermCount document term count Globals: none Returns: 0 on success, -1 on error */ static int iPrsFinishDocument ( struct prsParser *pppPrsParser, struct prsFormat *ppfPrsFormat, FILE *pfIndexerFile, unsigned char *pucFilePath, off_t zStartOffset, off_t zEndOffset, unsigned int uiDocumentTermCount ) { int iError = UTL_NoError; wchar_t pwcDocumentTitle[SPI_TITLE_MAXIMUM_LENGTH + 1] = {L'\0'}; wchar_t pwcDocumentKey[SPI_DOCUMENT_KEY_MAXIMUM_LENGTH + 1] = {L'\0'}; wchar_t pwcDocumentUrl[SPI_URL_MAXIMUM_LENGTH + 1] = {L'\0'}; unsigned int uiDocumentRank = 0; unsigned long ulDocumentAnsiDate = 0; ASSERT(pppPrsParser != NULL); ASSERT(ppfPrsFormat != NULL); ASSERT(pfIndexerFile != NULL); ASSERT(zStartOffset >= 0); ASSERT(zEndOffset >= 0); ASSERT(zEndOffset >= zStartOffset); ASSERT(uiDocumentTermCount >= 0); /* Get the document information */ if ( ppfPrsFormat->vPrsDocumentInformationFunction != NULL ) { ppfPrsFormat->vPrsDocumentInformationFunction(pucFilePath, pwcDocumentTitle, pwcDocumentKey, pwcDocumentUrl, &uiDocumentRank, &ulDocumentAnsiDate); } /* Clean the title and document key from extraneous characters that may have crept in */ iUtlStringsTrimWideString(pwcDocumentTitle); iUtlStringsTrimWideString(pwcDocumentKey); /* Use the base name of the file path as the title if we have no title */ if ( (bUtlStringsIsWideStringNULL(pwcDocumentTitle) == true) && (bUtlStringsIsStringNULL(pucFilePath) == false) ) { unsigned char *pucFilePathBasePtr = NULL; swprintf(pwcDocumentTitle, SPI_TITLE_MAXIMUM_LENGTH + 1, L"%s", (iUtlFileGetPathBase(pucFilePath, &pucFilePathBasePtr) == UTL_NoError) ? pucFilePathBasePtr : pucFilePath); } /* Send the document title ** H title{A} (Title) */ if ( fprintf(pfIndexerFile, "H %ls\n", pwcDocumentTitle) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a title line to the indexer"); } /* Send the date ** D date{D} (Document ansi date - optional) */ if ( ulDocumentAnsiDate > 0 ) { if ( fprintf(pfIndexerFile, "D %lu\n", ulDocumentAnsiDate) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a date line to the indexer"); } } /* There is no date or date/time defined, so we get them from the file we are parsing */ else if ( bUtlStringsIsStringNULL(pucFilePath) == false ) { time_t tTime = (time_t)0; struct tm tmTime; unsigned char pucDateString[UTL_FILE_PATH_MAX + 1] = {'\0'}; /* Get the date and time from the file */ if ( iUtlFileGetPathModificationTimeT(pucFilePath, &tTime) == UTL_NoError ) { s_localtime_r(&tTime, &tmTime); s_strftime(pucDateString, UTL_FILE_PATH_MAX, "%Y%m%d%H%M%S", &tmTime); if ( fprintf(pfIndexerFile, "D %s\n", pucDateString) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a date line to the indexer"); } } } /* Send the rank ** R rank{N}] (Document rank - optional) */ if ( uiDocumentRank > 0 ) { if ( fprintf(pfIndexerFile, "R %u\n", uiDocumentRank) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a rank line to the indexer"); } } /* Send the document key if needed ** K key{A} (document key - optional) */ if ( bUtlStringsIsWideStringNULL(pwcDocumentKey) == false ) { if ( fprintf(pfIndexerFile, "K %ls\n", pwcDocumentKey) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document key line to the indexer"); } } else { if ( pppPrsParser->uiDocumentKey > 0 ) { if ( fprintf(pfIndexerFile, "K %u\n", pppPrsParser->uiDocumentKey) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document key line to the indexer"); } } } /* Send the term count ** C count{N} (term count - optional) */ if ( fprintf(pfIndexerFile, "C %u\n", uiDocumentTermCount) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a term count line to the indexer"); } /* Send the item information ** I itemName{A} mimeType{A} length{N} [filepath{A} start{N} end{N}] [URL{A}] (Document types and source files) */ if ( pppPrsParser->ppaPrsAssociation == NULL ) { if ( fprintf(pfIndexerFile, "I %s %s %ld", (pppPrsParser->pucItemName != NULL) ? pppPrsParser->pucItemName : ppfPrsFormat->pucItemName, (pppPrsParser->pucMimeType != NULL) ? pppPrsParser->pucMimeType : ppfPrsFormat->pucMimeType, (long)(zEndOffset - zStartOffset)) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } if ( (pppPrsParser->bStoreFilePaths == true) && (bUtlStringsIsStringNULL(pucFilePath) == false) ) { if ( fprintf(pfIndexerFile, " %s %ld %ld", pucFilePath, (long)zStartOffset, (long)(zEndOffset - 1)) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } } if ( bUtlStringsIsWideStringNULL(pwcDocumentUrl) == false ) { if ( fprintf(pfIndexerFile, " %ls", pwcDocumentUrl) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } } if ( fprintf(pfIndexerFile, "\n") < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } } else if ( bUtlStringsIsStringNULL(pucFilePath) == false ) { unsigned int uiI = 0; for ( uiI = 0; uiI < pppPrsParser->uiPrsAssociationLength; uiI++ ) { unsigned char pucSavedFilePath[UTL_FILE_PATH_MAX + 1] = {'\0'}; unsigned char *pucSavedFilePathPtr = NULL; s_strnncpy(pucSavedFilePath, pucFilePath, UTL_FILE_PATH_MAX + 1); /* Strip the current extension, but not the period (add a period if it is not there) */ if ( (pucSavedFilePathPtr = (unsigned char *)s_strrchr(pucSavedFilePath, '.')) != NULL ) { *pucSavedFilePathPtr = '\0'; } /* Append the extension to the file path */ s_strnncat(pucSavedFilePath, (pppPrsParser->ppaPrsAssociation + uiI)->pucExtension, UTL_FILE_PATH_MAX, UTL_FILE_PATH_MAX + 1); /* Check to see if the file is there */ if ( bUtlFilePathRead(pucSavedFilePath) == true ) { off_t zFileLength = 0; /* Get the file length */ if ( (iError = iUtlFileGetFilePathLength(pucSavedFilePath, &zFileLength)) != UTL_NoError ) { iUtlLogError(UTL_LOG_CONTEXT, "Failed to get length of the file: '%s', utl error: %d.", pucSavedFilePath, iError); return (-1); } if ( fprintf(pfIndexerFile, "I %s %s", (pppPrsParser->ppaPrsAssociation + uiI)->pucItemName, (pppPrsParser->ppaPrsAssociation + uiI)->pucMimeType) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } if ( (pppPrsParser->bStoreFilePaths == true) && (bUtlStringsIsStringNULL(pucFilePath) == false) ) { if ( fprintf(pfIndexerFile, " %ld %s 0", (long)zFileLength, pucSavedFilePath) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } } if ( fprintf(pfIndexerFile, " %ld\n", (long)(zFileLength - 1)) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a document type line to the indexer"); } } } } /* Send end of document marker ** E (End of document marker) */ if ( fprintf(pfIndexerFile, "E\n") < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a end of document line to the indexer"); } /* Increment the number of documents */ pppPrsParser->uiDocumentCount++; /* Check to see if we have reached the document count limit and generate a message if we have */ if ( (pppPrsParser->uiDocumentCountMax > 0) && (pppPrsParser->uiDocumentCount >= pppPrsParser->uiDocumentCountMax) ) { if ( bUtlStringsIsWideStringNULL(pwcDocumentKey) == false ) { iUtlLogInfo(UTL_LOG_CONTEXT, "Reached maximum number of documents to parse (%u), last document key: '%ls'.", pppPrsParser->uiDocumentCountMax, pwcDocumentKey); if ( fprintf(pfIndexerFile, "M Reached maximum number of documents to parse (%u), last document key: '%ls'\n", pppPrsParser->uiDocumentCountMax, pwcDocumentKey) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer"); } } else { if ( pppPrsParser->uiDocumentKey > 0 ) { iUtlLogInfo(UTL_LOG_CONTEXT, "Reached maximum number of documents to parse (%u), last document key: '%u'.", pppPrsParser->uiDocumentCountMax, pppPrsParser->uiDocumentKey); if ( fprintf(pfIndexerFile, "M Reached maximum number of documents to parse (%u), last document key: '%u'\n", pppPrsParser->uiDocumentCountMax, pppPrsParser->uiDocumentKey) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer"); } } else { iUtlLogInfo(UTL_LOG_CONTEXT, "Reached maximum number of documents to parse (%u).", pppPrsParser->uiDocumentCountMax); if ( fprintf(pfIndexerFile, "M Reached maximum number of documents to parse (%u)\n", pppPrsParser->uiDocumentCountMax) < 0 ) { iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer"); } } } } /* Increment the document key */ if ( pppPrsParser->uiDocumentKey > 0 ) { pppPrsParser->uiDocumentKey++; } return (0); }