I'm trying to write a CGI script in c++ which prints the reverse network path (using
traceroute) from the web server to the IP address of the client invoking the CGI script.
When I run the program in Visual Studio, it works fine(creates the process, prints the result into "C:/result.out" file, opens the file, prints each line from file, closes file) BUT after compiling and trying to run just its .exe file, it throws an exception. What could I do to make the .exe work properly ?
Just as a note, I'm using Windows XP and Visual C++ 2008
Here`s the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>
int main()
{
char *line, *command, *userIp;
printf("Content-Type:text/html\n\n");
printf("<html><head></head><br/>");
printf("<body><br/>");
line = (char*)malloc(255*sizeof(char));
command = (char*)malloc(10*sizeof(char));
userIp = (char*)malloc(30*sizeof(char));
//userIp = getenv("REMOTE_ADDR"); // use a default IP until program works
strcpy(command,"tracert ");
strcpy(userIp,"74.125.87.104");
strcat(command,userIp);
strcat(command," > C:/result.out");
// create command "tracert 74.125.87.104 > C:/result.out"
printf("%s",command);
system(command);
FILE *f;
f = fopen("C:/result.out","r"); // open C:/result.out and read line - by - line
strcpy(line,"");
while(!feof(f)){
fgets(line,255,f);
printf("%s\n",line);
}
fclose(f);
printf("<br/>Test running OK<br/>");
printf("</body></html>");
getch();
return 0;
}
Most likely your web server (sanely) doesn't have permission to write to c:\. Either use a proper location for temporary files, or have tracert stream the results back to the executable so you can capture them.
Well the following two lines cause buffer over-runs
strcat(command,userIp);
strcat(command," > C:/result.out");
So this is likely the result of a crash.
Please do not use the term "Exception" unless an exception is being thrown, and since you are writing C code that is unlikely. So it is not an exception.
Rather than running a command using system() and piping the result to a file use the popen() command this will run a command and pipe the output to a stream that you can read just like a file (but without the security implications of writing to the file system).
FILE *f;
f = popen(command,"r"); // run the command. The std out goes to the FILE stream
^^^^^^
strcpy(line,"");
while(!feof(f)){
fgets(line,255,f);
printf("%s\n",line);
}
fclose(f);
Related
I have a code for file write using FILE Library, and usually works, but I found a case where doesn't work: When the code runs concurrently with filebeat process.
I don't know this cause of the problem because my c++ project does not support debugging mode.
I am participating in an open source project developed by someone else and i am not familiar with this project yet.
This is my c++ code:
FILE *fptr;
fptr = fopen("log_path.c_str()", "w");
if (fptr == NULL)
{
printf("Error!");
exit(1);
}
fprintf(fptr, "%s", log.c_str());
fclose(fptr);
Is there a any other good way to save log files?
Please give me some advice.
Your code have broken-pipe exception when you try to write a file.
This exception occurs when a c++ code try to write a log file while the filebeat software is reading the log file.
So, I recommend using this C++ code:
#include <fstream>
#include <iostream>
logFilePath = "this is path string of log file";
log = "this is log string";
ofstream output(logFilePath, ios::app);
output << log << endl;
output.close();
This code that used the offstream library will be solve the broken pipe exception.
If you use this c++ code, it is able to use string type for file write process, so it's not necessary to type convert via c_str().
I checked that this code able to used with File beat 7.10.0.
Thank you.
I wrote a simple Windows C++ service (Visual Studio 2012), which starts, listens on a port and also prints log messages to a file.
This is the startup code:
#include <stdlib.h>
#include "MyHeader.h"
int main()
{
if(!InitAndStartService())
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
Within InitAndStartService, I call StartServiceCtrlDispatcher and open my logging file writing a couple of messages to it.
The problem I'm facing is that the file is never created. The file I/O logic is written using CreateFile and WriteFile.
I even tried putting in the following code snippet in the main right before the if condition:
FILE *file = fopen("temp.txt", "w");
char *str = "hi";
fwrite((void *)str, 1, strlen(str), file);
fclose(file);
But the file is still not created. I had also put in a check such that if the file handle returned from fopen was NULL, I'd directly exit without going into InitAndStartService so that the SCM would give an error. But it turns out that the file handle isn't null.
The service does start and stop properly, but I don't see the port being open using netstat while it is running. The service is running as Local System, and has the required permissions to write to the folder.
What could be the reasons for this behaviour, and how can I dig further into this ?
I've been working on this project, and I'll do my best to explain what I'm doing.
I will run a bat file from native DOS (USB DOS Boot thumbdrive) that starts a program (SHOWDATA.EXE) and outputs some data from that program to a text file. Then it will launch my app (compiled for DOS16Bit with Open-Watcom) which modifies a second exe file (EDITED.EXE) using information that was just previously output. Then it should run the newly modified exe (EDITED.EXE). My Environments for testing have been in Virtual Box and using a USB DOS bootable drive. So far my system and program runs as intended until the line where I display 'Finished' and want to Launch the newly modified exe, I get a
General failure reading drive C
Abort, Retry, Ignore, Fail?
Virtual Box here also displays a write Error to Drive A (Floppy drive A)
If I restart the system, I can then run the newly modified file without issue and have the desired results.
Is there a problem with the way I am opening or editing or closing my file that would cause this behavior?
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE * pFile;
char data1[11];
char data2[33];
pFile = fopen ("testfile.exe","r+b");
printf ("PROGAM TITLE TEXT\n");
printf ("2013\n");
printf ("\n");
printf("Enter 10 Digit String from 1st filed above:\n"); //From previous program output
scanf ("%10s",data1); //only read 10 Chars
printf("Enter 32 Digits from 2nd field above:\n"); //From previous program output
scanf ("%32s",uuid); //only read 32 Chars
fseek (pFile,24523,SEEK_SET);//file offset location to begin write
fputs (sn,pFile); //Write our data!
fseek (pFile,24582,SEEK_SET);//file offset location to begin write
fputs (uuid,pFile); //Write our data!
fseek (pFile,24889,SEEK_SET);//file offset location to begin write
fputs (uuid,pFile); //Write our data!
fclose(pFile); //Close our file
printf ("Finished\n");
return(0);
}
My Bat file looks like this, where I pass a variable from text file "D.txt" to SHOWDATA.EXE and write the output to info.txt. I then parse info.txt with a FOR /F to display only useful information that will be used to edit the second exe file (EDITED.EXE). Then it will launch the edited exe file.
TYPE D.txt | SHOWDATA.EXE > Info.txt
PAUSE
MYPROGRAM.EXE
PAUSE
EDITED.EXE
I'm at a loss.
I have a C++ program which has the prototype of the main function as follows:
int main(int argc, char * argv[])
The code hasn't been written by me, but this is a single C file available here.
When I compile this code, and through the command line run it as:
someexe in.txt > out.txt
This gives me an output out.txt which is generated in the same directory by operating on some input from in.txt.
someexe in.txt out.txt
This gives me an output on the command line itself. (without using > operator)
However, instead of passing the command line argument and without using the output redirection > operator, I have been trying to call the main function from another function and passing the parameters myself. If I pass an array of char* {fileDirName, in.txt}, I am not sure how to go about generating an out.txt (since I think > output redirection is an operating system level function available in command line).
Any suggestions would be greatly appreciated
The program in the link is readily available as copy paste and can be tried (main function is written at the last in the above program)
Assuming the aim is to mimic the output redirection feature (> out.txt) of the shell you can do something like:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <iostream>
int main() {
int fd = open("out.txt", O_WRONLY|O_CREAT|O_TRUNC, 0660);
assert(fd >= 0);
const int ret = dup2(fd, 1);
assert(ret >= 0);
std::cout << "Hello redirected world!" << std::endl;
close(fd);
}
You can do similar for stdin also, to mimic the input redirection (< in.txt). These will be preserved across calls to exec() too.
Of course it would be simpler to modify the program to write to the place you wanted given you have the source available.
Note though that dup2(), which "swap" the stdout fd for the one we just opened is non-portable. IIRC open() (as opposed to fopen()) is UNIX specific also)
You can't call another main() from inside the source another program - main() is special.
If you want to reuse this source code as a library you need to rename main() to something else.
However if it is handling input from either a pipe or a file (eg myprog < input.txt or myprog input.txt) in the normal Unix way then that's a little trickier to handle transparently.
The best way would be to call the compiled program as a separate process from within your new program, passing the correct commandline parameters - see the exec() family of calls
I'm planning to package OpenTibia Server for Debian. One of the things I want to do is add startup via /etc/init.d and daemonization of the otserv process.
Thing is, we should probably redirect output to syslog. This is usually done via the syslog() function. Currently, the code is swarmed with:
std::cout << "Stuff to printout" << std::endl;
Is there a proper, easy to add, way to redirect standard output and standard error output into syslog without replacing every single "call" to std::cout and friends?
You can pipe your stdout to syslog with the logger command:
NAME
logger - a shell command interface to the syslog(3) system log module
SYNOPSIS
logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...]
DESCRIPTION
Logger makes entries in the system log. It provides a shell command
interface to the syslog(3) system log module.
If you don't supply a message on the command line it reads stdin
You can redirect any stream in C++ via the rdbuf() command. This is a bit convoluted to implement but not that hard.
You need to write a streambuf that would output to syslog on overflow(), and replace the std::cout rdbuf with your streambuf.
An example, that would output to a file (no error handling, untested code)
#include <iostream>
#include <fstream>
using namespace std;
int main (int argc, char** argv) {
streambuf * yourStreamBuffer = NULL;
ofstream outputFileStream;
outputFileStream.open ("theOutputFile.txt");
yourStreamBuffer = outputFileStream.rdbuf();
cout.rdbuf(yourStreamBuffer);
cout << "Ends up in the file, not std::cout!";
outputFileStream.close();
return 0;
}
Not sure whether a straight "C" answer suffices; but in "C" you can use underlying stdio features to plug the (FILE*) directly into syslog calls, without an intervening "logger" process. Check out
http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/
Try wrapping the execution of the binary with a suitable script, that just reads stdout and stderr, and send any data read from them on using syslog(). That should work without any code changes in the wrapped application, and be pretty easy.
Not sure if there are existing scripts to pipe into, but writing one shouldn't be hard if not.
I just wrote some code that will do this. It's using ASL instead of syslog, and it's using kevents, so you may need to port it to different APIs for your system (syslog instead of ASL and poll/select instead of kevent)
http://cgit.freedesktop.org/xorg/app/xinit/tree/launchd/console_redirect.c
Furthermore, I basically added this to libsystem_asl on Mountain Lion. Check out the man page for asl_log_descriptor.
Example:
#include <asl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
fprintf(stdout, "This is written to stdout which will be at log level info.");
fprintf(stderr, "This is written to stderr which will be at log level notice.");
return 0;
}