Nagios plugin (written in C) unable to open file - nagios

I have a plugin written in c that will parse a .log file and determine the page hit count:
_xLogFileName = "./loging.log";
/* File operation starts here */
_xFile = fopen ( _xLogFileName, "r" );
if ( _xFile != NULL )
{
//read a line upto the end of the file
while ( fgets ( _xFileLine , sizeof _xFileLine, _xFile ) != NULL )
{
// #_xTiemInStr --> cur date in YYYY-MM-DD format to identify todays log
if(strstr(_xFileLine, _xTiemInStr) != NULL) {
if(strstr(_xFileLine, _xLoginHitString) != NULL) {
_xLoginPageCounter = _xLoginPageCounter + 1;
}
}
}
printf("Usage:Total Login Page Hit :%d\n",_xLoginPageCounter );
fclose ( _xFile );
return 0;
}
else
{
printf("error\n");
perror ( _xLogFileName );
return 3;
}
return 0;
Now I placed the a.out file in /usr/lib/nagios/plugin folder and placed the "loging.log" file in the same folder- for both chmod 777 done. I can run the plugin from command line but when I integrate the same with nagios then it is giving unknown status and printing the "error" from else part-- can anyone please help
2nd part
In addition I added the following code to determine from where the nagios is running?
char cwd[1024];
_xLogFileName1 = "loging.log";
if (getcwd(cwd, sizeof(cwd)) != NULL)
_xLogFileName = strcat( cwd,_xLogFileName1);
printf("FileName : %s\n", _xLogFileName);
and it is printing /loging.log in status information?
So where I have to actually place the file, my nagios is running from /etc/nagios3 and I placed the loging.log file there also but still it is not working.
UPDATE: Now it is working, as I print the pwd by the c program and find that it is running from my root (/) dir , so I placed the loging.log file there and now it is working fine.

You should be passing the full path to the file and storing that in '_xLogFileName1', and not just the file name alone. Strongly recommend that you do not copy files into the root directory.
Knowing web logs, it is very likely that the date string you're looking for is at the front of the line. So I'd recommend using 'strnstr' instead of 'strstr'. It would greatly improve your search speed.

Related

Fopen function returns null when given an existing path

When trying to open a file with fopen(path, "2"); i get NULL on an existing path
iv'e tried to enter only the file name and it works but i want the program to write the file in the path...
Yes, i write the path with double backslashes "\\" when it's necesary.
Yes the path without doubt exists.
FILE* log;
char directory_path[PATH_LEN] = { 0 };
char directory_file[PATH_LEN] = { 0 };
//directory_path is the directory, entered by the user
//LOG_NAME is the files name without the path - "log.txt"
//#define PATH_LEN 100
printf("Folder to scan: ");
fgets(directory_path, PATH_LEN, stdin);
directory_path[strlen(directory_path) - 1] = 0;
//this section connects the path with the file name.
strcpy(directory_file, directory_path);
strcat(directory_file, "\\");
strcat(directory_file, LOG_NAME);
if ((log = fopen(directory_file, "w")) == NULL)
{
printf("Error");
}
My program worked until i tried to write into a file in order to create a log file. This means that the path is correct without doubt.
Can anyone tell me the problem here?
You have several issues in your code:
For one, fopen(path, "2"); is not valid.
The mode argument needs to include one of a, r, and w and can optionally include b or +.
As another thing, directory_path[strlen(directory_path) - 1] = 0; may truncate the end of your path (if it's over PATH_LEN characters long).
There also may be a possible issue with buffer overflow due to the fact that you copy a string to a buffer of the same size and then concatenate two other strings to it. Therefore, you should change this line:
char directory_file[PATH_LEN] = { 0 };
to this:
char directory_file[PATH_LEN+sizeof(LOG_NAME)+1] = { 0 };
To debug this issue, you should print the string entered and ask for confirmation before using it (wrap this in #ifdef DEBUG).

play .wav file using c language

I was asked to play .wav files using C language, the compiler I'm using is Devcpp.
I was trying to use the function PlaySound() as below:
PlaySound("C:/Users/wavfiles/13.1.wav", NULL, SND_FILENAME);
If I directly input the directory to the function like this, it is able to successfully play the sound.
However, I want to set the directory as a variable. I create a text file with a list of directory and extract the one that I want, then put it into PlaySound() function. Here is part of my code:
FILE *fw;
char addr[1000]
char schapter[50];
while(fgets(addr, 1000, fw) != NULL) {
if((strstr(addr, schapter)) != NULL) {
printf("\n%s", addr);
PlaySound(addr, NULL, SND_FILENAME);
}
}
In this case, the directory is assigned to addr (addr = "C:/Users/wavfiles/13.1.wav") and then I put addr into PlaySound(), but it doesn't work.
I have been stuck on this problem for a long time and cannot move on.
I would really appreciate it if anyone can give me suggestions or solutions.
Thank you.
The string returned by fgets() contains the terminal newline. You'll need to remove that to get the filename.
An easy way to do this is to use strchr() to locate the newline:
while (fgets(addr, 1000, fw) != NULL) {
char *nl = strchr(addr, '\n');
if (nl) *nl = 0;
…
}

Extension issue for renamed file for FIle Reading in C / C++

I have a code for reading the header of a csv file. First I check whether the extenson is .csv or not. Then I read the file. But the problem is, if I rename any other file, say a .xml file or a .docx file to .csv and then try to read it, then this file extension check doesn't work. It then crashes.
But I want to throw a proper error in such cases. Can anyone help? Here are the relevant code snippets:
// Extracting the extension of the file. Since only csv files are allowed,
// for rest of the extensions, appropriate error is being thrown
sExt = wcsrchr(sFile, L'.');
if(wcscmp(sExt, L".csv") != 0)
{
return -1;
}
_wfopen_s(&fpInpFile, sFile, L"rt");
if(fpInpFile == NULL)
{
return -1;
}
while(sChar[lCharIndx] = fgetwc(fpInpFile))
{
lVarLength ++;
lHeaderLength ++;
// If Variable name is too long, or if the length of the header is too long, throw an error
if(lVarLength >= 100 || lHeaderLength >= 100)
{
fclose(fpInpFile);
return -1;
}
// Resetting varibale length before reading length of next variable
if(sChar[lCharIndx] == ',')
lVarLength = 0;
// Header reading is done, so exiting the loop
if(sChar[lCharIndx] == '\n')
break;
lCharIndx ++;
}
fclose(fpInpFile);
while(sChar[lCharIndx] = fgetwc(fpInpFile))
You should't check for end-of-file this way. Instead:
wint_t wch;
while ((wch = fgetwc(fpInpFile)) != WEOF)
{
sChar[lCharIndx] = wch;
Also, you should check whether lCharIndx is within array size of sChar or not.

why minizip doesn't archive large file (larger 4 GB)

I am trying to use static minizip library on Windows 7 64-bit, using Visual Studio 2010.
The main goal is to archive files larger 4GB.
I build zlib using CMake 2.8, and linked in to my project.
It works for files less 4GB, but doesn't work proper for files larger 4GB.
Why I have a problem with archiving 5GB file using minizip?
Did I miss something on the build libraries stage?
Here are all my steps, library and project: https://github.com/koponomarenko/file_compression
Really need help. Thanks.
Updated:
"doesn't work proper for files larger 4GB" means that my test program archives 5GB txt file without any errors during this process. I checked zipWriteInFileInZip() returns ZIP_OK for all 5,368,709,120 bytes. zipCloseFileInZip() and zipClose() don't return any errors. But in created archive (I use 7-zip) file info is:
Uncompressed size: 4,294,967,295
Compressed size: 8,806,676
Attributes: empty field
CRC: 81970625
Method: Deflate
Host OS: FAT
Version: 45
And I get error message "Unsupported compression method" when try to unzip (using 7-zip) this archive.
I also zipped the same 5GB txt file with 7-zip. Here is file info from this archive:
Uncompressed size: 5,368,709,120
Compressed size: 9,608,471
Attributes: A
CRC: 81970625
Method: Deflate
Host OS: FAT
Version: 45
The first 3 fields are different from my archive.
Updated:
void Archive::create()
{
m_archiveHandle = zipOpen64(m_sName.c_str(), APPEND_STATUS_CREATE);
if ( !m_archiveHandle )
{
throw Error("Can't create the archive. Can be already created.");
}
}
void Archive::add(string sSrcFile, string sDstFile)
{
//////////////////////////// create a file
zip_fileinfo zfi;
memset(&zfi, 0, sizeof(zfi));
int zip64 = 1;
int ret = zipOpenNewFileInZip64(m_archiveHandle,
sDstFile.c_str(),
&zfi,
NULL, 0,
NULL, 0,
"my comment for this interior file",
Z_DEFLATED,
Z_DEFAULT_COMPRESSION,
zip64
);
if ( ret != 0 )
{
throw Error("Can't add file to a zip archive.");
}
//////////////////////////// write to the file
FILE * pFile = fopen( sSrcFile.c_str(), "rb" );
if ( !pFile )
{
throw Error("Can't open target file.");
}
char * buf = new char[BUF_SIZE];
int size_read = 0;
int err;
do
{
err = ZIP_OK;
size_read = (int)fread(buf, 1, BUF_SIZE, pFile);
if (size_read < BUF_SIZE)
if ( feof(pFile) == 0 )
{
err = ZIP_ERRNO;
}
if (size_read > 0)
{
err = zipWriteInFileInZip (m_archiveHandle, buf, size_read);
}
} while ((err == ZIP_OK) && (size_read>0));
delete [] buf;
//////////////////////////// close the file
if ( zipCloseFileInZip(m_archiveHandle) != 0 )
{
throw Error("Can't close added file.");
}
}
void Archive::close()
{
if ( !m_archiveHandle )
return;
if ( zipClose(m_archiveHandle, "my comment for exterior file") != 0)
{
throw Error( "Can't save changes and close." );
}
m_archiveHandle = 0;
}
I use this batch file to get static Zlib. I put it in zlib/build64 and run from "Visual Studio x64 Win64 Command Prompt".
rem ** go to the current script directory
cd %~dp0
cmake .. -G"Visual Studio 10 Win64" -DCMAKE_INSTALL_PREFIX="C:\devel\installed\zlib64"
msbuild /P:Configuration=Debug INSTALL.vcxproj
msbuild /P:Configuration=Release INSTALL.vcxproj
Updated:
Created archive can be unzipped by Total Commander and Windows Explorer. I compared a check-sum (md5, sha1) of the original file and unzipped file, and it was the same. But neither Total nor Explorer shows attributes of the compressed file. Meanwhile 7-zip says me "Unsupported compression method".
Updated December 09, 2013:
It seems that minizip has some problems with attributes when work with files larger 4GB on Windows. 7-Zip and WinZip can't unzip created archive.
The problem is in order of fields (extra field and file comment field) for Central Directory Record in ZIP. So if your file is bigger than 4GB and you added a comment for it you are going to face this bug.
It seems to me that the original author stopped maintenance this library, but I found a repo with some fresh changes on Github here https://github.com/nmoinvaz/minizip . So I wrote about this bug to the author of this repo.

Trying to open a relative path in Ubuntu doesn't work

I'm trying the open a relative path in Ubuntu , but after opening the first folder - called 14 - the code fails to open the folder inside - called 15:
int pathsCtr; // number of folders in RelativeArray
char ** RelativeArray; // the folders in the relative path, currently:
RelativeArray[0] = "14";
RelativeArray[1] = "15";
// some code before
if (pathsCtr > 0 && flag == TRUE) // then we have a relative path
{
int j = 0;
while (j < pathsCtr) // run until the last path and open every one
{
printf("\n%s\n" , RelativeArray[j]);
dirp = opendir(RelativeArray[j]); // open all directories until the last one
if (dirp == NULL)
return -1;
j++; // proceed to the next directory
}
flag = FALSE; // turn off the flag , we'll never go near this again
}
When j == 0 this line : dirp = opendir(RelativeArray[j]); works and dirp is not NULL.
But when j == 1 that line dirp = opendir(RelativeArray[j]); fails and dirp is NULL .
What am I doing wrong?
EDIT:
Assume that I'm doing malloc for RelativeArray before the above code .
opendir() opens a directory for reading its contents, but it does not change the working directory of the process.
To access a subdirectory, you will have to specify it by its fully path relative to the current working directory (or else its absolute path).
You can probably do this by concatenating your strings with an appropriate separator character.
Since you don't seem to do anything with the directory stream pointer returned by opendir() other than check that it's non-null, there's a good chance this is not the function you want to be using. You may want to look at chdir() instead (man 2 chdir) but do think about any undesired consequences.

Resources