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.

Problem with Op Status Script

Old posts that have not been replied to for several years.
Locked
K
Kraka
Voice
Posts: 19
Joined: Thu Apr 21, 2005 9:25 pm

Problem with Op Status Script

Post by Kraka »

I am trying to run this script and i keep getting an error

Tcl error [checkidleops]: couldn't open "scripts/OPs.data": too many open files

I have it set to check to see if the ops are idiling every 30 mins. The first 30 mins it will be fine and catch the ops that are idiling, but then when it checks 30 mins after that it comes with that error. If anyone can please tell me how to fix this script i would appreciate it. Here is the code for the script:

#############################################################
###
### Operator Status v0.4:
### Allows Operators to set themself to away or available,
### users can simply type !status (or a custom command) and
### they will get the status for the operators currently on
### the channel. All works with public commands.
###
### Written by [ThEdGE] by the idea of [bi0h4z4rd].
###
### Install: add "source scripts/OPs.tcl" to your eggdrop.conf,
### and configure the options below!.
###
#############################################################

### Options

### Channel where the script will function.
set channel "#Chan"

### AutoAway feature, when a op is idle for X mins set automaticly away.
### Then when he says something when hes away, hes put back to active again.
### Default: 30 mins (set to "0" to disable)
set awaymins "30"

### Command that people will have to type to get the status of all ops.
### Default: !status
set cmd1 "!status"

### Command that ops will have to type to set themselfs on Available.
### Default: !on
set cmd2 "!on"

### Command that ops will have to type to set themselfs on Away.
### Default: !off
set cmd3 "!off"

### Small tag that will be shown in the text the bot will msg.
### Default: [OPs]
set systag "\037\[\037\002OPs\002\037\]\037"

### Nickname(s) to ignore, usually bots.
set ignorednicks {
"ChanServ"
"X"
"Y"
}

### Shows a extra line when !status is triggered for the ignored nicks,
### use this when you added bots to it, it will show a line like:
### Bots on this channel: <nicknames>, just for information to the users.
### Default: "0", set "1" to enable.
set showbots "1"

### Enable logging, when enabled it will log events like when op put himself on
### away or active, and when someone requests a status in the eggdrop log.
### Default: "1", use 0 to disable.
set logging "1"

### Path and filename of the Plain text database
### Default: scripts/OPs.data
set dbpath "scripts/OPs.data"


### Dont touch the code below, or it will fux0r :)
#############################################################
#############################################################


bind PUB - $cmd1 cmd1
bind PUB - $cmd2 cmd2
bind PUB - $cmd3 cmd3

bind time - "?? * * * *" checkidleops

### Procedure which will check if the ops are idle or not.
###################################################################################
proc checkidleops {minute hour day month year} {
global channel systag ignorednicks showbots dbpath awaymins

### Check if autoaway is disabled.
if {$awaymins == "0"} { return }

### Check if database file exists, make one if needed.
if {[catch { open $dbpath r } error]} {
set dbnew [open $dbpath w]
fconfigure $dbnew -blocking 0
close $dbnew
}

### Create the channel op list, and remove ignorednicks
set oplist
  • foreach nickn [chanlist $channel] {
    if {[isop $nickn $channel]} {
    set ignore "0"
    foreach inick $ignorednicks {
    set nickn2 $nickn
    set nickn2 [string tolower $nickn2]
    set inick [string tolower $inick]
    if {$nickn2 == $inick} {
    set ignore "1"
    }
    }
    if {$ignore == "0"} {
    set oplist [linsert $oplist end $nickn]
    }
    }
    #close oplist if
    }
    # Close oplist foreach

    ### Read in database.
    set db [open $dbpath r]
    fconfigure $db -blocking 0
    set nicklist
    • while {![eof $db]} {
      set line [gets $db]
      if {$line != ""} {
      set nicklist [linsert $nicklist end $line]
      }
      }
      close $db

      ### Check if ops are idle and check if they are already away or not.
      set db [open $dbpath w]
      fconfigure $db -blocking 0
      foreach op $oplist {
      set ndupe "0"
      set idle [getchanidle $op $channel]
      if {$idle > "$awaymins"} {
      foreach nickn $nicklist {
      if {$nickn == $op} {
      set ndupe "1"
      puts $db "$nickn"
      }
      }
      }

      ### Op has been idle, set away.
      if {$ndupe == "0" && $idle > "$awaymins"} {
      puts $db "$op"
      putserv "NOTICE $op : $systag You have been idle for more then $awaymins mins on $channel you are now set on : \002Away\002"
      log " $op has been put on away (autoaway)"
      }
      }
      close $db
      }
      # end proc


      ### Procedure which will echo the user the information about ops away or active.
      ###################################################################################
      proc cmd1 { nick uhost handle chan arg} {
      global channel systag ignorednicks showbots dbpath
      log "$nick requested the operater status"

      ### Check if this is the right channel to function on.
      set chan [string tolower $chan]
      set channel [string tolower $channel]
      if {$chan != $channel} { return }

      ### Check if database file exists, make one if needed.
      if {[catch { open $dbpath r } error]} {
      set dbnew [open $dbpath w]
      fconfigure $dbnew -blocking 0
      close $dbnew
      }

      ### Open away database for reading.
      set db [open $dbpath r]
      fconfigure $db -blocking 0

      ### Create various lists used in the script.
      set nicklist
      • set oplist
        • set tempawaylist
          • set awaylist
            • set activelist
              • ### Read database and insert everything in a temp awaylist.
                while {![eof $db]} {
                set line [gets $db]
                if {$line != ""} {
                set tempawaylist [linsert $tempawaylist end $line]
                }
                }
                close $db

                ### Validate awaylist by checking if the users are in the chan and opped.
                foreach nickn $tempawaylist {
                if {[isop $nickn $chan]} {
                set awaylist [linsert $awaylist end $nickn]
                }
                }

                ### Create the channel op list, and remove ignorednicks
                foreach nickn [chanlist $chan] {
                if {[isop $nickn $chan]} {
                set ignore "0"
                foreach inick $ignorednicks {
                set nickn2 $nickn
                set nickn2 [string tolower $nickn2]
                set inick [string tolower $inick]
                if {$nickn2 == $inick} {
                set ignore "1"
                }
                }
                if {$ignore == "0"} {
                set oplist [linsert $oplist end $nickn]
                }
                }
                #close oplist if
                }
                # Close oplist foreach

                ### Extract the active people from the OP list.
                foreach nicko $oplist {
                set away 0
                foreach nicka $awaylist {
                if {$nicko == $nicka} {
                set away 1
                }
                }
                if {$away == 0} {
                set activelist [linsert $activelist end $nicko]
                }
                }
                ### Format a row of nicks who are active.
                set activenicks ""
                foreach nickn $activelist {
                if {$activenicks == ""} {
                set activenicks "$nickn"
                } else {
                set activenicks "$activenicks, $nickn"
                }
                }
                ### Format a row of nicks who are away.
                set awaynicks ""
                foreach nicka $awaylist {
                if {$awaynicks == ""} {
                set awaynicks "$nicka"
                } else {
                set awaynicks "$awaynicks, $nicka"
                }
                }

                ### Echo the user the result of the active operators.
                if {$activenicks != ""} {
                putserv "NOTICE $nick : $systag Operators who are Available : $activenicks"
                } else {
                putserv "NOTICE $nick : $systag There are no Operators Available at this time"
                }

                ### Echo the user the result of the away operators.
                if {$awaynicks != ""} {
                putserv "NOTICE $nick : $systag Operators who are Away : $awaynicks"
                } else {
                putserv "NOTICE $nick : $systag There are no Operators Away at this time"
                }

                ### Echo the user the bot info if enabled.
                if {$showbots == "1"} {
                set bots ""
                foreach bot $ignorednicks {
                if {[isop $bot $chan]} {
                if {$bots == ""} {
                set bots "$bot"
                } else {
                set bots "$bots, $bot"
                }
                }
                }
                if {$bots != ""} {
                putserv "NOTICE $nick : $systag Bots on this channel are : $bots"
                } else {
                putserv "NOTICE $nick : $systag There are no Bots in this channel at this time."
                }
                }

                }
                # close proc


                ### Procedure which will put a Op on active
                ###################################################################################
                proc cmd2 { nick uhost handle chan arg} {
                global systag channel dbpath

                ### Check if this is the right channel to function on.
                set chan [string tolower $chan]
                set channel [string tolower $channel]
                if {$chan != $channel} { return }

                ### Read in database
                set db [open $dbpath r]
                fconfigure $db -blocking 0
                set nicklist
                • while {![eof $db]} {
                  set line [gets $db]
                  if {$line != ""} {
                  set nicklist [linsert $nicklist end $line]
                  }
                  }
                  close $db

                  ### Update database and echo result.
                  set db [open $dbpath w]
                  fconfigure $db -blocking 0

                  foreach nickn $nicklist {
                  if {$nickn != $nick} {
                  puts $db "$nickn"
                  }
                  }
                  close $db
                  putserv "NOTICE $nick : $systag You are now set to : \002Available\002"
                  log " $nick has put him/herself on Available."
                  }


                  ### Procedure which will put a Op on away
                  ###################################################################################
                  proc cmd3 { nick uhost handle chan arg} {
                  global systag channel dbpath

                  ### Check if this is the right channel to function on.
                  set chan [string tolower $chan]
                  set channel [string tolower $channel]
                  if {$chan != $channel} { return }

                  ### Read in database.
                  set newnick "0"
                  set db [open $dbpath r]
                  fconfigure $db -blocking 0
                  set nicklist
                  • while {![eof $db]} {
                    set line [gets $db]
                    if {$line != ""} {
                    set nicklist [linsert $nicklist end $line]
                    }
                    }
                    close $db

                    ### Write new database and echo the result
                    set db [open $dbpath w]
                    fconfigure $db -blocking 0
                    foreach nickn $nicklist {
                    if {$nickn == $nick} {
                    set newnick "1"
                    puts $db "$nick"
                    } else {
                    puts $db "$nickn"
                    }
                    }

                    if {$newnick == "0"} {
                    puts $db "$nick"
                    putserv "NOTICE $nick : $systag You are now set to : \002Away\002"
                    log " $nick has put him/herself on Away."
                    } else {
                    putserv "NOTICE $nick : $systag You are already set to : \002Away\002"
                    }
                    close $db

                    }

                    proc log {text} {
                    global logging
                    if {$logging == "1" && $text != ""} {
                    putlog "\[OPs\] $text"
                    }
                    }

                    putlog "Operator Status v0.4 Loaded!"
                    ### EOF
                    ### OPs (c) ThEdGE [www.thedge.de]
User avatar
Sir_Fz
Revered One
Posts: 3794
Joined: Sun Apr 27, 2003 3:10 pm
Location: Lebanon
Contact:

Post by Sir_Fz »

Code: Select all

if {[catch { open $dbpath r } error]} { 
 set dbnew [open $dbpath w] 
 fconfigure $dbnew -blocking 0
 close $dbnew 
}
the file $dbpath is being opened in the catch statement but not closed, thus that error (too many open files). You need to close it. try replace the above code with:

Code: Select all

if {[catch {set bla [open $dbpath r]} error]} { 
 set dbnew [open $dbpath w] 
 fconfigure $dbnew -blocking 0 
 close $dbnew 
} 
close $bla
Last edited by Sir_Fz on Tue Jun 14, 2005 4:49 pm, edited 1 time in total.
User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

lame script, opening and closing the same file zillion of times, probably messing up in-between, given that's done on timer every minute

don't use it, or at least post it using

Code: Select all

 tags, maybe some generous soul will be willing to waste their time to fix it (which I very much doubt)
Locked