/**************************************************************************/
// pipe.cpp - Functions which pipe to the operating system
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with the dawn license *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
**************************************************************************/
#include "include.h"
// Local functions.
char *fgetf( char *s, int n, FILE *iop );
/**************************************************************************/
void do_pipe( char_data *ch, char *argument )
{
char buf[16000], pbuf[MSL];
FILE *fp;
if (IS_NPC(ch))
{
do_huh(ch,"");
return;
}
if (!(IS_TRUSTED(ch,MAX_LEVEL) && ch->level>=MAX_LEVEL-1)
&& !is_exact_name(TRUE_CH(ch)->name,"_impossible_name@#$!"))
{
do_huh(ch,"");
return;
}
sprintf(pbuf,"%s", argument);
ch->printlnf("piping '%s'",pbuf);
fp = popen( pbuf, "r" );
if(!fp){
ch->println("Pipe failed!");
return;
}
fgetf( buf, 15000, fp );
strcat (buf,"\r\n--=== END OF PIPE ===--\r\n");
ch->sendpage(buf);
pclose( fp );
return;
}
/**************************************************************************/
void do_system( char_data *ch, char *argument )
{
char buf[5000];
if (IS_NPC(ch))
{
do_huh(ch,"");
return;
}
if (!(IS_TRUSTED(ch,MAX_LEVEL) && ch->level>=MAX_LEVEL-1)
&& !is_exact_name(TRUE_CH(ch)->name,"_impossible_name@#$!"))
{
do_huh(ch,"");
return;
}
#ifdef WIN32
sprintf(buf,"%s", argument);
#else
sprintf(buf,"%s &", argument);
#endif
system(buf);
ch->printlnf("performed a system '%s'", buf);
return;
}
/**************************************************************************/
char *fgetf( char *s, int n, FILE *iop )
{
int c;
char *cs;
c = '\0';
cs = s;
while( --n > 0 && (c = getc(iop)) != EOF){
if ((*cs++ = c) == '\0'){
break;
}
}
*cs = '\0';
return((c == EOF && cs == s) ? (char*)"" : s);
}
/**************************************************************************/
char * get_piperesult( char *cmd )
{
static char buf[16000];
char pbuf[MSL];
FILE *fp;
sprintf(pbuf,"%s", cmd);
fp = popen( pbuf, "r" );
if(!fp){
return ("get_piperesult failed!");
}
fgetf( buf, 15900, fp );
pclose( fp );
return (buf);
}
/**************************************************************************/
// displays the dead directory
void do_checkdead( char_data *ch, char *)
{
char buf[MSL],buf2[MSL];
BUFFER *output;
output= new_buf();
#ifdef unix
sprintf( buf,"ls -lart " DEAD_DIR);
#else
sprintf( buf,"dir " DEAD_DIR);
#endif
sprintf( buf2,"\r\n`?%s`x", makef_titlebar("CHECK DEAD - Piping:`x %s", buf));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
sprintf( buf2,"`^%s`x", makef_titlebar("-"));
add_buf(output,buf2);
ch->sendpage(buf_string(output));
free_buf(output);
}
/**************************************************************************/
// displays the dead directory
void do_checklog( char_data *ch, char *argument)
{
char buf[MSL],buf2[MSL];
BUFFER *output;
output= new_buf();
if(IS_NULLSTR(argument)){
#ifdef unix
sprintf( buf,"ls -lart " PLAYER_LOGS_DIR);
#else
sprintf( buf,"dir " PLAYER_LOGS_DIR);
#endif
sprintf( buf2,"\r\n`?%s`x", makef_titlebar("CHECKLOG - Piping:`x %s", buf));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
sprintf( buf2,"`^%s`x", makef_titlebar("-"));
add_buf(output," To read a log: checklog <playername> <number of lines>\r\n");
add_buf(output," <number of lines> - shows up to 40 lines worth.\r\n");
add_buf(output,buf2);
}else{
char * pc;
char name[MIL], linenums[MIL];
char logfile_name[MIL];
char command[MIL];
// split off the name from the line numbers
argument = one_argument( argument, name);
one_argument( argument, linenums);
// filter the name for non alpha characters
for ( pc = name; *pc != '\0'; pc++ )
{
if ( !is_alpha(*pc) )
{
ch->printlnf("CHECKLOG: %s is not a valid player name", name);
free_buf(output);
return;
}
}
// check log file exists
sprintf(logfile_name, "%s%s.log", PLAYER_LOGS_DIR, name);
if(!file_exists(logfile_name)){
ch->printlnf("CHECKLOG: There is no logfile called %s", logfile_name);
free_buf(output);
return;
}
if(!IS_NULLSTR(linenums) && is_number(linenums)){
int value = atoi(linenums);
if (value<1 || value>30000)
{
add_buf(output,"\r\n`RNumber of lines to read of log must be between 1 and 30000.`x\r\n");
free_buf(output);
return;
}
else
{
sprintf(command, "tail -n %d %s | head -n 40", value, logfile_name);
}
}else{
sprintf(command, "tail -n 20 %s", logfile_name);
add_buf(output, "\r\n== You can select the number of loglines, type checklog <playername> <number of lines>==\r\n");
}
sprintf( buf,"`?%s`x", makef_titlebar("CHECKLOG"));
add_buf(output,buf);
sprintf( buf,"\r\n`^%s`x", makef_titlebar("Piping:`x %s", command));
add_buf(output,buf);
add_buf(output,get_piperesult(command));
}
ch->sendpage(buf_string(output));
free_buf(output);
}
/**************************************************************************/
// displays the wholist from port 1234
void do_who1234( char_data *ch, char *)
{
char buf[MSL*5],buf2[MSL*5];
BUFFER *output;
output= new_buf();
#ifdef unix
sprintf( buf,"lynx -auth=disable:password -nolog -dump http://127.0.0.1:1239/immwho");
#else
ch->println("unix only");
return;
#endif
sprintf( buf2,"\r\n`?%s`x", makef_titlebar("Remote wholist - port 1234"));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
sprintf( buf2,"`^%s`x", makef_titlebar("-"));
add_buf(output,buf2);
ch->sendpage(buf_string(output));
free_buf(output);
}
/**************************************************************************/
// displays the wholist from port 4321
void do_who4321( char_data *ch, char *)
{
char buf[MSL*5],buf2[MSL*5];
BUFFER *output;
output= new_buf();
#ifdef unix
sprintf( buf,"lynx -auth=disable:password -nolog -dump http://127.0.0.1:4326/immwho");
#else
ch->println("unix only");
return;
#endif
sprintf( buf2,"\r\n`?%s`x", makef_titlebar("Remote wholist - port 4321"));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
sprintf( buf2,"`^%s`x", makef_titlebar("-"));
add_buf(output,buf2);
ch->sendpage(buf_string(output));
free_buf(output);
}
/**************************************************************************/
char *is_valid_scriptname(char *scriptname);
/**************************************************************************/
#define IRCLOGS_DIR (game_settings->irclogs_dir)
/**************************************************************************/
// displays the irclog directory - Kal - Aug 99
void do_checkirc( char_data *ch, char *argument)
{
char buf[MSL],buf2[MSL];
BUFFER *output;
char tbuf[MIL];
output= new_buf();
if(IS_NULLSTR(argument)){
#ifdef unix
sprintf( buf,"ls -lart %s", IRCLOGS_DIR);
#else
sprintf( buf,"dir %s", IRCLOGS_DIR);
#endif
sprintf( buf2,"\r\n`?%s`x", makef_titlebar("CHECKIRC - Piping:`x %s", buf));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
sprintf( buf2,"`^%s`x", makef_titlebar("-"));
add_buf(output," To read a log: checkirc <logname> <number of lines>\r\n");
add_buf(output," Checkirc if it doesn't find an exact match on the filename,\r\n");
add_buf(output," Will automatically attempt combinations of .log and .<date> for you.\r\n");
add_buf(output," <number of lines> - shows up to 40 lines worth.\r\n");
add_buf(output,buf2);
}else{
char name[MIL], linenums[MIL];
char logfile_name[MIL];
char command[MIL];
// split off the name from the line numbers
argument = first_arg(argument, name, false);
argument = first_arg(argument, linenums, false);
// filter the name for non alpha characters
if(is_valid_scriptname(name)){
ch->printlnf("CHECKIRC: %s is not a valid log filename", name);
free_buf(output);
return;
}
{ // get the time buffering
struct tm *today;
today=localtime( ¤t_time);
strftime(tbuf, MIL, "%d%b", today);
char t2buf[10]; // budget fix to get rid of y2k compiler warning
strftime(t2buf, 10, "%Y", today);
strcat(tbuf,&t2buf[0]);
logf(tbuf);
}
// try 4 different formattings to match the filename
for(int count=0; count<4; count++)
{
switch(count){
case 0: // straight
// check log file exists
sprintf(logfile_name, "%s%s", IRCLOGS_DIR, name);
break;
case 1: // with .<date>
// check log file exists
sprintf(logfile_name, "%s%s.%s", IRCLOGS_DIR, name, tbuf);
break;
case 2: // with .log
// check log file exists
sprintf(logfile_name, "%s%s.log", IRCLOGS_DIR, name);
break;
case 3: // with .log.<date>
// check log file exists
sprintf(logfile_name, "%s%s.log.%s", IRCLOGS_DIR, name, tbuf);
break;
}
if(file_exists(logfile_name)){
break;
}
}
if(!file_exists(logfile_name)){
ch->printlnf("CHECKLOG: There is no logfile called %s, nor without the added extensions.", logfile_name);
free_buf(output);
return;
}
if(!IS_NULLSTR(linenums) && is_number(linenums)){
int value = atoi(linenums);
if (value<1 || value>30000)
{
add_buf(output,"\r\n`RNumber of lines to read of log must be between 1 and 30000.`x\r\n");
free_buf(output);
return;
}
else
{
sprintf(command, "tail -n %d %s | head -n 40", value, logfile_name);
}
}else{
sprintf(command, "tail -n 20 %s", logfile_name);
add_buf(output, "\r\n== You can select the number of loglines, type checklog <playername> <number of lines>==");
}
sprintf( buf,"`?%s`x", makef_titlebar("CHECKIRC"));
add_buf(output,buf);
sprintf( buf,"\r\n`^%s`x", makef_titlebar("Piping:`x %s", command));
add_buf(output,buf);
add_buf(output,get_piperesult(command));
}
ch->sendpage(buf_string(output));
free_buf(output);
}
/**************************************************************************/
// display the bug listing - Daos, Sep 01
void do_checkbug( char_data *ch, char *argument)
{
char buf[MSL], buf2[MSL];
char arg1 [MIL];
BUFFER *output=new_buf();
sprintf( buf,"`?%s`x", makef_titlebar("`#`WCODE-BUG LOGFILE`^"));
add_buf(output,buf);
// now display the specified number of lines of the log file.
argument = one_argument( argument, arg1 );
if (IS_NULLSTR(arg1)){
strcpy(buf, "tail -n 10 " BUG_FILE );
add_buf(output, "\r\n You can select the number of loglines, type `#`Ycheckbug <number of lines>`^");
}else if (is_number ( arg1 )){
int value = atoi(arg1);
if (value<1 || value>20000){
add_buf(output,"\r\n`RNumber of lines to tail must be between 1 and 20000.`x\r\n");
strcpy(buf, "tail -n 10 " BUG_FILE );
}else{
sprintf(buf, "tail -n %d " BUG_FILE " | head -n 40", value);
}
}else{
add_buf(output, "\r\n`RThe only parameter for this command must be a "
"numeric value\r\nfor the number of lines of the ooc "
"log you wish to see.`x\r\n");
strcpy(buf, "tail -n 10 " BUG_FILE );
}
sprintf( buf2,"\r\n`^%s`x", makef_titlebar("Piping:`x %s", buf));
add_buf(output,buf2);
add_buf(output,get_piperesult(buf));
ch->sendpage(buf_string(output));
free_buf(output);
return;
}
/**************************************************************************/
// display the bug listing - Daos, Sep 01
/*
void do_checkevent( char_data *ch, char *argument)
{
char buf[MSL], buf2[MSL];
char arg1 [MIL];
BUFFER *output=new_buf();
sprintf( buf,"Recent Events\r\n");
add_buf(output,buf);
// now display the specified number of lines of the log file.
argument = one_argument( argument, arg1 );
if (IS_NULLSTR(arg1)){
strcpy(buf, "tail -n 10 " EVENT_FILE );
}else if (is_number ( arg1 )){
int value = atoi(arg1);
if (value<1 || value>20000){
add_buf(output,"\r\n`RNumber of lines to tail must be between 1 and 20000.`x\r\n");
strcpy(buf, "tail -n 10 " EVENT_FILE );
}else{
sprintf(buf, "tail -n %d " EVENT_FILE " | head -n 40", value);
}
}else{
add_buf(output, "\r\n`RThe only parameter for this command must be a "
"numeric value\r\nfor the number of lines of the ooc "
"log you wish to see.`x\r\n");
strcpy(buf, "tail -n 10 " EVENT_FILE );
}
add_buf(output,get_piperesult(buf));
ch->sendpage(buf_string(output));
free_buf(output);
return;
}
*/
/**************************************************************************/
/**************************************************************************/