Im working in c (more or less for the first time) for uni, and I need to generate an MD5 from a character array. The assignment specifies that this must be done by creating a pipe and executing the md5 command on the system.
I've gotten this far:
FILE *in;
extern FILE * popen();
char buff[512];
/* popen creates a pipe so we can read the output
* of the program we are invoking */
char command[260] = "md5 ";
strcat(command, (char*) file->name);
if (!(in = popen(command, "r"))) {
printf("ERROR: failed to open pipe\n");
end(EXIT_FAILURE);
}
Now this works perfectly (for another part of the assignment which needs to get the MD5 for a file) but I cant workout how to pipe a string into it.
If I understand correctly, I need to do something like:
FILE * file = popen("/bin/cat", "w");
fwrite("hello", 5, file);
pclose(file);
Which, I think, would execute cat, and pass "hello" into it through StdIn. Is this right?
If you need to get a string into the md5 program, then you need to know what options your md5 program works with.
If it takes a string explicitly on the command line, then use that:
md5 -s 'string to be hashed'
If it takes standard input if no file name is given on the command line, then use:
echo 'string to be hashed' | md5
If it absolutely insists on a file name and your system supports /dev/stdin or /dev/fd/0, then use:
echo 'string to be hashed' | md5 /dev/stdin
If none of the above apply, then you will have to create a file on disk, run md5 on it, and then remove the file afterwards:
echo 'string to be hashed' > file.$$; md5 file.$$; rm -f file.$$
See my comment above:
FILE* file = popen("/sbin/md5","w");
fwrite("test", sizeof(char), 4, file);
pclose(file);
produces an md5 sum
Try this:
static char command[256];
snprintf(command, 256, "md5 -qs '%s'", "your string goes here");
FILE* md5 = popen(md5, "r");
static char result[256];
if (fgets(result, 256, md5)) {
// got it
}
If you really want to write it to md5's stdin, and then read from md5's stdout, you're probably going to want to look around for an implementation of popen2(...). That's not normally in the C library though.
Related
I'm making essentially a terminal wrapper. I want my program to read from stdin, and for any inputs that come in, echo it EXACTLY the way it is, even if it's wrong.
Right now, I'm doing:
FILE *output = popen(buffer, "r");
memset(buffer, '\0', BUFF_SIZE * 2);
while (fgets(buffer, sizeof(buffer), output) != 0)
{
printf("%s", buffer);
memset(buffer, '\0', BUFF_SIZE * 2);
}
pclose(output);
}
where I'm calling shell commands using popen, but in certain situations, for example, when the command is not found, the output returned by using popen won't be exactly the same compared to when using the terminal without the wrapper. For example, if I input $ asd, linux terminal will return
No command 'asd' found, but there are 24 similar ones
asd: command not found
whereas popen will return:
sh: 1: asd not found
I would like to have the default terminal response rather than what popen returns, would this be possible? If so, how?
I have a binary file which prints the result instead of returning the value, if I execute it using cmd I am getting printed text, I managed to execute it from C code but it seems like I can not get the text it usually prints to be stored in a variable I can use later for further decisions.
I do not have that much of experience in C and I googled a lot.
I came across the idea of using clip but my cmd is saying that clip command can not be found.
any help or ideas would be appreciated.
The correct function pair to use on POSIX systems is popen() and
pclose(). You can perhaps use Microsoft's _popen() and
_pclose() unless the warning 'This API cannot be used in applications that execute in the Windows Runtime' matters to you.
You would use it more or less like this. I've had to invent the name of the command you wish to execute since the question doesn't specify that. I chose ./example.exe as the name — and I'm assuming it needs no arguments.
char cmd[] = "./example.exe";
FILE *fp = popen(cmd, "r");
if (fp != NULL)
{
char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(buffer), sizeof(char), fp)) != 0)
{
…process nbytes of data…
…it is not a null-terminated string unless you add the null byte…
}
pclose(fp);
}
else
{
…report error for failure to execute command…
}
You can use the system function from <stdlib.h> to run the command you want. To get the command's output, you modify your command like in this question to save the command's output to a file. Then you can use the file I/O functions in <stdio.h> to process the command output.
In Linux, you may do command substitution and pass its result as arguments to the program, Something like this
./your_program "$(/path/to/your/binary/file)"
Suppose your main is
int main(int argc,char* argv[]){
.
.
return 0;
}
Acess the arguments like argv[1] and so.
Here the $(command) does the substitution and it passes the printed values from the binary as arguments to the pgm. Hope this helps.
Use snprintf function. For e.g.
snprintf(cmdbuff, BUFFER_LEN, "dmidecode --type 17 | grep -i Size | grep -o '\\<[0-9]*\\>' | paste -sd+ | bc");
Here cmdbuff is character array where command will be stored , BUFFER_LEN is a size of the character array
Then use popen and fgets to get the output of command into some buffer as shown below
if((fd = popen(cmdbuff,"r")) != NULL)
{
fgets(buffer, BUFFER_LEN, fd);
sprintf(vnfc_configured_memory, "%s", buffer);
vnfc_configured_totalRAM = atof(vnfc_configured_memory);
}
I'm using "system" API calls to run shell commands in my C program, now
there is case where I want to redirect the output generated by an executableto a buffer instead of a file (named recv.mail)
An example of how I write the output to the file:
cmd[] = "mda "/bin/sh -c 'cat > recv.mail'";
system (cmd);
Similarly I want to replace input taken from the file (send.mail) with input taken from a buffer.
An example of how I take input from a file:
cmd[] = "msmtp < cat send.mail";
system (cmd);
NOTE: The send.mail and recv.mail files have formatted data.
Are pipes a better replacement?
Can anyone suggest another alternative?
popen/pclose may do what you want:
FILE *f = popen("program to execute", "r");
if (NULL != f)
{
char buffer[128];
while (fgets(buffer, sizeof buffer, f)
{
printf("Read from program: '%s'\n", buffer);
}
pclose (f);
}
popen/pclose again:
FILE *f = popen("program to execute", "w");
...
In C, stdin is a valid file pointer, thus we could use stdin (and the 2 others) with the "file" version of the input functions if we want or need to.
Why might us need to (Rather than just pipe in from shell)? Could anyone come up with some examples please?
Here's an example:
FILE * input = argc == 2 ? fopen(argv[1], "r") : stdin;
fgets(buf, sizeof buf, input);
Now you can use your tool as magic data.txt and as magic < data.txt.
If you write a function that works on any FILE *, and at a higher level you decide that you want the output to go to stdout. Or read from any FILE * and instead you decide to read from stdin.
If you at, for example, the program wc which counts characters in a file, you'll see that it can read from stdin or from a file name given as a command line argument. This decision could be made in the main by checking to see if the user provided a file name with $ wc file.txt or called with just wc, or piped input from something else $ ls -l | wc
$ wc # reads from stdin
$ wc file.txt # counts characters in file.txt
$ ls -l | wc # reads from stdin also.
and you can imagine a simple main which says:
int count_chars(FILE *in);
int main(int argc, char *argv) {
if (argc == 2) { // if there is a command line argument
FILE *input = fopen(argv[1], "r"); // open that file
count_chars(input); // count from that file
} else {
count_chars(stdin); // if not, count from stdin
}
return 0;
}
Additionally to print errors one would use fprintf(stderr, "an error occured\n");
I was wondering what's the best way to read in a filename in C when the name is echoed on the command line, as in: if I type in
echo test.txt | a1
how would I access the test.txt using
fopen(fname, "r");?
When you pipe data from one program to another it's as if you typed the output of the first into the second. In this case the file name can be read from stdin, and one way to read it is with the fgets function.
Read data from the standard input.
Process the data.
#include <stdio.h>
char buf[1024];
while (fgets(buf, sizeof buf, stdin))
{
printf("Read line: '%s'\n", buf);
FILE * fp = fopen(buf, "r");
if (fp)
{
// process the file
fclose(fp);
}
else
{
printf("No such file: %s\n", buf);
}
}
The obvious caveat is that the file name may be longer than 1023 characters; read the manual for fgets for details on how to detect this.
The way it's written, you'll do one processing attempt per line, and the program stops when the input stream ends.
You're trying to read from stdin, which means you could use fread (man 3 fread on *nix, here if you aren't.) to read from it.
stdin is just a name for a standard file-descriptor, so you can read from it like any other file.