This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

bot dies (ping timeout), when script is triggered

Help for those learning Tcl or writing their own scripts.
Post Reply
r
rix
Halfop
Posts: 42
Joined: Wed Sep 21, 2005 1:04 pm
Location: Estonia

bot dies (ping timeout), when script is triggered

Post by rix »

Hello!

It seems that my bot keeps dieing when "big" scripts are triggered. Such like pisg-0.5.tcl. Bot dies with error message "Ping timeout" when pisg is executed and log file is being analyzed.

The code should be okay, but why does bot die?

Another mixed script, that generates statistics but bot dies in middle of it:

Code: Select all

set pisgver "0.70"

#Location of pisg execuitable perl script
set pisgexe "/home/rix/pisg/pisg"

#URL of the generated stats
set pisgurl "http://www.starpump.ee/jutukas/stats"

#channel that the stats are generated for
set pisgchan "#starpump"

#Users with these flags can operate this function
set pisgflags "nm"

#How often the stats will be updated in minutes, ie: 30 - stats will be updated every 30 minutes
set pisgtime "60"

set pisg_server "starpump.ee"
set pisg_user "user0071"
set pisg_pass "******"
set pisg_localdir "/home/rix/pisg/index.html"
set pisg_remotedir "stats"

bind pub $pisgflags !statsup pub:pisgcmd

proc pub:pisgcmd {nick host hand chan arg} {
   global pisgexe pisgurl pisgchan
   if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "okay" }
   if {$out == "okay"} {
    puthelp "PRIVMSG $pisgchan :Statistika on edukalt koostatud, jätkan üleslaadimist..."
    set pisg_localfile "$pisg_localdir"
    set pisg_remotefile "$pisg_remotedir/index.html"
    pisg_sendftp $pisg_localfile $pisg_server $pisg_user $pisg_pass $pisg_remotefile
   }
   else {
    puthelp "PRIVMSG $pisgchan :$out"
   }
   puthelp "PRIVMSG $pisgchan :Statistika on üles laetud: $pisgurl"
}

proc pisgcmd_timer {} {
   global pisgexe pisgurl pisgchan pisgtime
   append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" }
   puthelp $out
   timer $pisgtime pisgcmd_timer
}

if {![info exists {pisgset}]} {
  set pisgset 1
  timer 2 pisgcmd_timer
}

proc pisg_sendftp { localfile server user pass remotefile } {
  global pingcheck
  if {![file exist $localfile]} {
    return "sendftp: $localfile ei eksisteeri."
  }
  set noftp [catch {set ftpprog [exec which ftd]}]
  if {$noftp} {
    if {[file executable /usr/bin/ftp]} {
      set ftpprog /usr/bin/ftp
      set noftp 0
    }
    if {[file executable /bin/ftp]} {
      set ftpprog /bin/ftp
      set noftp 0
    }
  }
  if {$noftp} { return "sendftp: Sul puudub 'ftp' tööriist" }

  set pipe [open "|$ftpprog -n $server" w]
  puts $pipe "user $user $pass"
  puts $pipe "bin"
  puts $pipe "put $localfile $remotefile"
  puts $pipe "quit"
  close $pipe
  return 1
}

putlog "pisg.tcl $pisgver loaded"
User avatar
rosc2112
Revered One
Posts: 1454
Joined: Sun Feb 19, 2006 8:36 pm
Location: Northeast Pennsylvania

Post by rosc2112 »

Lack of thread support in the bot?
User avatar
DragnLord
Owner
Posts: 711
Joined: Sat Jan 24, 2004 4:58 pm
Location: C'ville, Virginia, USA

Post by DragnLord »

If you are running the eggdrop from a unix-like shell; you would probably do well to use bgexec, or change the script to implement the screen program if available on your shell server by using

Code: Select all

set pisgexe "/usr/local/bin/screen /home/rix/pisg/pisg"
(this assumes that the screen program is located at /usr/local/bin/screen, using

Code: Select all

which screen
at shell prompt will tell you where it is if it is installed)
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

One option might also be to execute it with

Code: Select all

open "|/home/rix/pisg/pisg" "RDWR"
, setting the file-descriptor to nonblocking mode (using fconfigure), and implement some fileevents to keep track on when it completes (the file-descriptor goes eof). Should work on most platforms.

You could probably also try this:

Code: Select all

...
  if {[catch {exec $pisgexe &} error]} {...
This one should not require any further actions, however you will not be able to read any stdout output from pisg (not that you do so now either)
NML_375
r
rix
Halfop
Posts: 42
Joined: Wed Sep 21, 2005 1:04 pm
Location: Estonia

Post by rix »

Yeah, i like the idea of using screen, but it gave error:
[20:29:07] <StarBot> usr/bin/screen /home/rix/pisg/pisg an error occured: Couldn't execute "usr/bin/screen /home/rix/pisg/pisg": no such file or directory

Even though usr/bin/screen is a correct location of screen.

The open function works very well, bot doesn't halt. Unfortunately i have defunct processes now:
13419 ? Z 4:31 [pisg] <defunct>

It seems that my whole code is very dodgy. Aargh, let it be then. Thanks for support though. :)
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

you'll have to close the file-descriptor opened by the open-command once it completes, hence the fileevents. Otherwize you'll end up with stale or zombified processes.
Did you try the "catch {exec $pisgexe &} error" approach?
NML_375
r
rix
Halfop
Posts: 42
Joined: Wed Sep 21, 2005 1:04 pm
Location: Estonia

Post by rix »

Yeah, the close function was absolutely missing. Also im not very sure where should i place the close function. Atm processes are still defuncted.

Code: Select all

set pisgver "0.70"

#Location of pisg execuitable perl script
set pisgexe [open "|/home/rix/pisg/pisg" "RDWR"]

#URL of the generated stats
set pisgurl "http://www.starpump.ee/jutukas/stats"

#channel that the stats are generated for
set pisgchan "#starpump"

#Users with these flags can operate this function
set pisgflags "nm"

#How often the stats will be updated in minutes, ie: 30 - stats will be updated every 30 minutes
set pisgtime "60"

set pisg_server "starpump.ee"
set pisg_user "user0071"
set pisg_pass "******"
set pisg_localdir "/home/rix/pisg/index.html"
set pisg_remotedir "stats"

bind pub $pisgflags !statsup pub:pisgcmd

proc pub:pisgcmd {nick host hand chan arg} {
   global pisgexe pisgurl pisgchan
   if {[catch {exec $pisgexe &} error]} { append out "$pisgexe an error occured: [string totitle $error]" } 
   else { 
     catch {close $pisgexe}
     set status "okay"
     }
   if {$status == "okay"} {
     puthelp "PRIVMSG $pisgchan :Statistika on edukalt koostatud, jätkan üleslaadimist..."
     set pisg_localfile "$pisg_localdir"
     set pisg_remotefile "$pisg_remotedir/index.html"
     sendftp $pisg_localfile $pisg_server $pisg_user $pisg_pass $pisg_remotefile
   }
   else {
     puthelp "PRIVMSG $pisgchan :$out"
   }
   puthelp "PRIVMSG $pisgchan :Statistika on üles laetud: $pisgurl"
}

proc pisgcmd_timer {} {
   global pisgexe pisgurl pisgchan pisgtime
   append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" }
   puthelp $out
   timer $pisgtime pisgcmd_timer
}

if {![info exists {pisgset}]} {
  set pisgset 1
  timer 2 pisgcmd_timer
}

putlog "pisg.tcl $pisgver loaded"
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Ohh.. seems you've mixed both of my two different approaches into one :/
if you go for the "catch {exec $pisgexe &} error" approach, leave pisgexe set to "/home/rix/pisg/pisg", not [open "|/home/rix/pisg/pisg" "RDWR"]

================================================================


In the case you'd like to go with the "command pipe"-option, you should still set pisgexe to "/home/rix/pisg/pisg". Then, when you wish to run the update, do something like this:

Open the command-pipe and set up a fileevent handler:

Code: Select all

set procID [open "|${pisgexe}" "RDWR"]
fileevent $procID readable [list checkpisg $procID]
This assumes there is a proc named "checkpisg" that is executed whenever there is readable output from pisg. It has two important tasks to perform, depending on the "end of file"-status of the process; 1. read a single line using "gets" (if not eof), and 2. close the command pipe (if eof).
In the case pisg generates an error, this will be returned when you try to close the command pipe.

A skeleton-proc for checkpisg; you'll probably wish to modify it to suite your needs:

Code: Select all

proc checkpisg {fileid} {
 if {![eof $fileid]} {
  #Read some data from pisg, pisg is still running
  set txt [gets $fileid]

 } else {
  if {[catch {close $fileid} error]} {
   #what to do if there's an error

  } else {
   #everything went ok

  }
 }
}
NML_375
User avatar
DragnLord
Owner
Posts: 711
Joined: Sat Jan 24, 2004 4:58 pm
Location: C'ville, Virginia, USA

Post by DragnLord »

quick note about screen:
if the location for screen is /usr/bin/screen, then you need to include the first /
"/usr/bin/screen /home/rix/pisg/pisg"
not
"usr/bin/screen /home/rix/pisg/pisg"
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

@DragnLord:
Actually, you can't have both paths within the same string.
In this case, the command should be "/usr/local/bin/screen", and it's first argument should be "/home/rix/pisg/pisg". You cannot concatenate command and arguments into a single string, and then execute it with exec

ie:

Code: Select all

exec "/usr/local/bin/screen /home/rix/pisg/pisg"   #Will not work
exec /usr/local/bin/screen /home/rix/pisg/pisg     #Will work
exec "/usr/local/bin/screen" "/home/rix/pisg/pisg" #Will work
NML_375
Post Reply