24 Jun, 2009, Banner wrote in the 1st comment:
Votes: 0
How could you perform a command in the shell and then return the output to the mud? IE:

pseudo code:
char cmd[1024];
int x;

sprintf( cmd, "wc -l *" );
system( cmd );
x = cmd;

chprintf( ch, "There are %d lines of code.", x );
24 Jun, 2009, David Haley wrote in the 2nd comment:
Votes: 0
IIRC, using the standard libraries, you need to open it as a pipe, and then read from the pipe until EOF (i.e. until the program closes its stdout, which almost always means that it has finished whatever it was doing). It's possible/likely that libraries exist to make this task much easier.
24 Jun, 2009, Runter wrote in the 3rd comment:
Votes: 0
You can use popen. But you'll have to do a bit of research; There's probably snippets available to make it work for our purposes right away.
24 Jun, 2009, Runter wrote in the 4th comment:
Votes: 0
24 Jun, 2009, Kline wrote in the 5th comment:
Votes: 0
http://www.ackmud.net/websvn/filedetails...

Just search for popen. I do some ugly things with it, but hey, it all works and I haven't managed to find a way to break it, yet :).
24 Jun, 2009, Sandi wrote in the 6th comment:
Votes: 0
I have a "safe" version of ferris@FootPrints' code, if you're interested.

Th raw version is cool, but be warned - kill <PID> does work! :evil:

(and so does: rm -rf *)
24 Jun, 2009, Cratylus wrote in the 7th comment:
Votes: 0
My comment may not be applicable to this situation, but I
feel compelled to foist it all the same, sry.

On my codebase there is an in-game way to run a system command.
It's called external_start(). The correct answer to "how do I run a
shell command from the mud
" for this codebase is "you use external_start().
make sure you address the fd correctly, and you might have to enable
some stuff at compile time.
"

However, the answer given most often is:

"You don't."

This is because if you have to ask how to do it, you don't know
how to do it safely, and really, it's almost always an awful idea.

Perhaps this doesn't apply here. I just thought I'd say it anyway.

-Crat
http://lpmuds.net
24 Jun, 2009, Banner wrote in the 8th comment:
Votes: 0
Kline said:
http://www.ackmud.net/websvn/filedetails...

Just search for popen. I do some ugly things with it, but hey, it all works and I haven't managed to find a way to break it, yet :).

This one looks different from the one Runter quoted. What's the difference, and how would you use it to print one line from something that returns several? Or make it move directories and so something, since I don't want line counts from the area folder. -_-


Sandi said:
I have a "safe" version of ferris@FootPrints' code, if you're interested.

Th raw version is cool, but be warned - kill <PID> does work! :evil:

(and so does: rm -rf *)

Does that mean you're sharing? :P And how is it safe if you can still destroy stuff with it?



Cratylus said:
My comment may not be applicable to this situation, but I
feel compelled to foist it all the same, sry.

On my codebase there is an in-game way to run a system command.
It's called external_start(). The correct answer to "how do I run a
shell command from the mud
" for this codebase is "you use external_start().
make sure you address the fd correctly, and you might have to enable
some stuff at compile time.
"

However, the answer given most often is:

"You don't."

This is because if you have to ask how to do it, you don't know
how to do it safely, and really, it's almost always an awful idea.

Perhaps this doesn't apply here. I just thought I'd say it anyway.

-Crat
http://lpmuds.net

I know it's a bad idea but the possibilities are pretty useful. Also, how unsafe is it if you tie it to one command that's at the highest level, named something obscure with no helpfiles, and no immortals are ever immortalized to that level save myself. Are there other safety measures to make it safer, regardless of the fact that one shouldn't do it to begin with? :P
24 Jun, 2009, Runter wrote in the 9th comment:
Votes: 0
As others have pointed out it's all language dependent. In C it's a little more involved than some of the libraries available in C++.

And in higher level scripting languages it's really seemless.

In Ruby, for example, it's this easy.
d = 'date'


^ to do the date shell command and set d to the results.
24 Jun, 2009, Guest wrote in the 10th comment:
Votes: 0
http://www.mudbytes.net/index.php?a=file...

The big red warning text isn't there lightly either. This sort of thing is rather dangerous, especially in the wrong person's hands.
24 Jun, 2009, David Haley wrote in the 11th comment:
Votes: 0
Well, if it's tied to the highest imm, then it's still only as secure as your MUD's command's security system. Do you trust that? I dunno, personally I wouldn't trust SMAUG's safety checks to protect my credit card information, for example. Keep in mind that if somebody were to get access to this command, they could completely take over your shell or at the very least do lots of very nasty things to you (such as rm -rf, as Sandi pointed out).

What exactly are you trying to do with it? There are probably safer ways of doing it.
24 Jun, 2009, Scandum wrote in the 12th comment:
Votes: 0
If you're calling predefined shell scripts it should be fairly safe.
24 Jun, 2009, Banner wrote in the 13th comment:
Votes: 0
David Haley said:
Well, if it's tied to the highest imm, then it's still only as secure as your MUD's command's security system. Do you trust that? I dunno, personally I wouldn't trust SMAUG's safety checks to protect my credit card information, for example. Keep in mind that if somebody were to get access to this command, they could completely take over your shell or at the very least do lots of very nasty things to you (such as rm -rf, as Sandi pointed out).

What exactly are you trying to do with it? There are probably safer ways of doing it.

Most of the suggestions posted are giving way more access that I want, IE I don't want to compile or be able to enter commands from the shell ect, basically all I want to do is be able to send a command and print the last line/targetted lines of output, like line counts.
24 Jun, 2009, Runter wrote in the 14th comment:
Votes: 0
Then install it but limit the access to a specific command. Here's a little something I threw together. I didn't test it, haven't compiled it, but who knows. It might work. ;)

char *shell_execute(char *command) {
static char buf[512]; // static so we can return it to caller
FILE *fp;
fp = popen(command, "r"); // open a pipe with command.

// read output into buf
fgetf( buf, 512, fp );
// close opened pipe
pclose(fp);
// return output to caller.
return buf;
}

// Reads output into str
void fgets( char *str, int length, FILE *fp ) {
char c = '\0';

// while we're not out of length
while(–length) {
// grab a character from the pipe and break if it is the EOF marker
if ((c = fgetc(fp)) == EOF)
break;
// copy this character into our passed buffer and break if it is a NULL delimiter.
if ((*str++ = c) == '\0')
break;
}
// Regardless, delimit the string will NULL to be sure.
*str = '\0';
}


That would let you do:
send_to_char(ch, shell_execute("ps xu"))


Or whatever. I think that's what you're wanting?

edit: fixed the comments.
24 Jun, 2009, David Haley wrote in the 15th comment:
Votes: 0
In that fgets code, you could be writing the \0 past the string bound if the length isn't long enough.

char buf[1];
fgets(buf, 1, bla);

–>

while(–length) {
… bla …
… str++ …
}
// str now points past the end of buf!
*str = '\0'; // oops


another reason to not like working with strings in C, eh…
24 Jun, 2009, Runter wrote in the 16th comment:
Votes: 0
David Haley said:
In that fgets code, you could be writing the \0 past the string bound if the length isn't long enough.

char buf[1];
fgets(buf, 1, bla);

–>

while(–length) {
… bla …
… str++ …
}
// str now points past the end of buf!
*str = '\0'; // oops


another reason to not like working with strings in C, eh…


I agree C strings are rubbish. But I'm going to have to disagree with you on the flaw in my code. ;) It should run just fine with no overrun.
24 Jun, 2009, Runter wrote in the 17th comment:
Votes: 0
#include <iostream>
using namespace std;

int main () {
int l = 1;

while (–l)
cout << "Any passes!" << endl;

cout << l << endl;
return 0;
}


We all know that –l is different from l–. So in this example l would be decremented before the condition check..

#include <iostream>
using namespace std;

int main () {
int l = 1;

while (l–)
cout << "Any passes!" << endl;

cout << l << endl;
return 0;
}


And in this code you would be right. l is decremented after the condition.
24 Jun, 2009, David Haley wrote in the 18th comment:
Votes: 0
Oh ya. I see x++ so much more than ++x that I didn't even realize it was in front… even after copy pasting it. Harrumph. At'll teach me for reading code too quickly. :redface:
24 Jun, 2009, flumpy wrote in the 19th comment:
Votes: 0
David Haley said:
Oh ya. I see x++ so much more than ++x that I didn't even realize it was in front… even after copy pasting it. Harrumph. At'll teach me for reading code too quickly. :redface:

*boggle*

guess we all have off days ;)
24 Jun, 2009, Sandi wrote in the 20th comment:
Votes: 0
Banner said:
Sandi said:
I have a "safe" version of ferris@FootPrints' code, if you're interested.

Th raw version is cool, but be warned - kill <PID> does work! :evil:

(and so does: rm -rf *)


Does that mean you're sharing? :P And how is it safe if you can still destroy stuff with it?


By "raw version" I meant Ferris'. My version only accepts specific commands, such as 'pipe char', which reads the top 20 lines of a pfile (useful to me because I rearranged the pfiles to put the interesting stuff at the top so it's like 'mstat'), 'pipe player', which does an 'ls' on the player dir, and 'pipe ps ux' which ought to be self-explanatory. :wink:

It also reads several files specific to DeepMUD, but it will not accept 'rm -rf *', so you're safe if someone finds a bug that makes them IMP level.

I share everything I do. It's all based on stuff freely given to me, so it only seems right to pass it on.
0.0/22