1# an example of script in sirc 2# by orabidoo '95 3# 4# .''', || '|| '||` 5# | | || || '' || 6# `||''|, | | ''||'' ||''|, || `||''|, .|''|, '||''|, || 7# || || | | || || || || || || || || || || || 8# .|| ||. `,,,' `|..' .|| || .||. .|| ||. `|..|| .. ||..|' .||. 9# || || 10# `..|' .|| 11# 12# 13# a generic toolbox for sirc; to load it, type /load n0thing.pl 14# 15# version 2.5, last modified: 12 June 1997 16# recent improvements: lots of new shortcut aliases, removed ctcp pong 17# replies, added /pj and /wall (from wallop.pl), 18# moved the settings into SET variables, store saved 19# msgs in memory, toggleable re-join/re-umode on 20# reconnect, toggleable ignore of duplicated aways, 21# better unig, and opbeg becomes ctcp op #chn pass. 22 23$add_ons.="+n0thing-v2.5.pl" if $add_ons !~ /n0thing/; 24 25$n_isaway=''; 26$n_svefile=$ENV{"HOME"}."/.n0thing-pl.sve"; 27 28# time saving aliases 29 30&docommand("^alias fing ctcp \$0 finger"); 31&docommand("^alias ver ctcp \$0 version"); 32&docommand("^alias tim ctcp \$0 time"); 33&docommand("^alias wallop wallops"); 34&docommand("^alias printuh set printuh"); 35&docommand("^alias printchan set printchan"); 36&docommand("^alias localhost set localhost"); 37&docommand("^alias logfile set logfile"); 38&docommand("^alias log set log"); 39&docommand("^alias ex system"); 40&docommand("^alias ls system ls -al"); 41&docommand("^alias cat system cat"); 42&docommand("^alias rm system rm"); 43&docommand("^alias ps system ps"); 44&docommand("^alias mail system mail"); 45&docommand("^alias setfing set finger"); 46 47sub cmd_open { 48 &getarg; 49 $newarg=$talkchannel unless $newarg; 50 &tell("*\cbE\cb* Huh? what channel?"), return unless $newarg; 51 $newarg =~ tr/A-Z/a-z/; 52 &sl("MODE $newarg -lsmpik ".$chankey{$newarg}); 53} 54&addcmd("open"); 55 56sub cmd_l { 57 if ($talkchannel) { 58 &sl("LIST $talkchannel"); 59 &sl("NAMES $talkchannel"); 60 } 61} 62&addcmd("l"); 63 64sub cmd_a { 65 if ($n_lastmsg) { 66 &msg($n_lastmsg, $args); 67 } else { 68 &tell("*\cbE\cb* How about sending a first /m to someone?"); 69 } 70} 71&addcmd("a"); 72 73sub cmd_pj { 74 if ($talkchannel) { 75 &sl("PART $talkchannel"); 76 &sl("JOIN $talkchannel"); 77 } 78} 79&addcmd("pj"); 80 81# dcc related stuff 82 83&docommand("^alias ds dcc send"); 84&docommand("^alias dl dcc list"); 85&docommand("^alias cdc dcc close chat"); 86&docommand("^alias cdg dcc close get"); 87&docommand("^alias cds dcc close send"); 88&docommand("^alias dcrename dcc rchat"); 89&docommand("^alias dcren dcc rchat"); 90&docommand("^alias rdc dcc rchat"); 91 92sub cmd_dc { 93 &getarg; 94 if ($newarg) { 95 &docommand("dcc chat $newarg"); 96 } elsif ($n_lastdc) { 97 &docommand("dcc chat $n_lastdc"); 98 $n_lastdc=''; 99 } 100} 101&addcmd("dc"); 102 103sub cmd_dg { 104 &getarg; 105 if ($newarg) { 106 &docommand("dcc get $newarg $args"); 107 } elsif ($n_lastdcc) { 108 &docommand("dcc get $n_lastdcc"); 109 $n_lastdcc=''; 110 } 111} 112&addcmd("dg"); 113 114# hooks 115 116sub hook_disc { 117 if ($n_rejoinchannels) { 118 $n_old_when=time; 119 $n_old_umode=$umode; 120 @n_old_channels=grep(!&eq($_, $talkchannel), @channels); 121 push(@n_old_channels, $talkchannel) if $talkchannel; 122 %n_old_chankey=%chankey; 123 } 124 &docommand("server 1"), $n_lastreconnect=time if 125 $n_reconnect && time-$n_lastreconnect>15; 126} 127&addhook("disconnect", "disc"); 128 129sub hook_reconnect { 130 if ($n_rejoinchannels && ($n_old_umode || @n_old_channels) && 131 time <= $n_old_when+15) { 132 $n_old_umode =~ tr/o//d; 133 &sl("MODE $nick +$n_old_umode") if $n_old_umode ne ''; 134 local($chans, $keys)=('', ''); 135 foreach $c (keys (%n_old_chankey)) { 136 $chans .= $c.","; 137 $keys .= $n_old_chankey{$c}.","; 138 } 139 foreach $c (@n_old_channels) { 140 $c =~ tr/A-Z/a-z/; 141 $chans .= $c."," unless defined($n_old_chankey{$c}); 142 } 143 $chans =~ s/,$//; 144 $keys =~ s/,$//; 145 &sl("JOIN $chans $keys") if $chans; 146 $n_old_umode=''; 147 @n_old_channels=(); 148 %n_old_chankey=(); 149 } 150} 151&addhook("001", "reconnect"); 152 153sub hook_ctcp { 154 if ($_[1] eq 'DCC') { 155 $n_lastdcc=$who if $_[2] =~ /^SEND /; 156 $n_lastdc=$who if $_[2] =~ /^CHAT /; 157 } 158} 159&addhook("ctcp", "ctcp"); 160 161sub hook_kicked { 162 local($kicked, $where_from, $reason)=@_; 163 if ($n_autorejoin && &eq($kicked, $nick)) { 164 &sl("JOIN $where_from $chankey{$where_from}"); 165 } 166} 167&addhook("kick", "kicked"); 168 169sub hook_uhnotify { 170 unless ($n_slowserver) { 171 &userhost($_[0], "&tell(\"*\cb)\cb* Signon by $_[0] (\$user\\\@\$host) detected!\");", ""); 172 $silent=1; 173 } 174} 175&addhook("notify_signon", "uhnotify"); 176 177sub hook_lastmsg { 178 $n_lastmsg=$_[0] unless $_[0] =~ /^[\#\+]/; 179} 180&addhook("send_text", "lastmsg"); 181&addhook("send_action", "lastmsg"); 182 183sub hook_away { 184 if ($n_awayonce && $_[0] =~ /^\S+\s+(\S+)\s/) { 185 local($l)=$1; 186 $l =~ tr/A-Z/a-z/; 187 $silent=1 if $n_aways{$l} eq $_[0]; 188 $n_aways{$l}=$_[0]; 189 } 190} 191&addhook("301", "away"); 192 193sub hook_whois { 194 if ($_[0] =~ /^\S+\s+(\S+)\s/) { 195 local($l)=$1; 196 $l =~ tr/A-Z/a-z/; 197 delete $n_aways{$l}; 198 } 199} 200&addhook("311", "whois"); 201 202# settings; create the $set{} variables with their default values here. 203 204sub set_autorejoin { 205 $set{'AUTOREJOIN'}="on", $n_autorejoin=1 if $_[0] =~ /^on$/i; 206 $set{'AUTOREJOIN'}="off", $n_autorejoin=0 if $_[0] =~ /^off$/i; 207} 208&addset("autorejoin"); 209$set{"AUTOREJOIN"}="on"; 210$n_autorejoin=1; 211&docommand("^alias rejoin set autorejoin"); 212 213sub set_rejoinchannels { 214 $set{'REJOINCHANNELS'}="on", $n_rejoinchannels=1 if $_[0] =~ /^on$/i; 215 $set{'REJOINCHANNELS'}="off", $n_rejoinchannels=0 if $_[0] =~ /^off$/i; 216} 217&addset("rejoinchannels"); 218$set{"REJOINCHANNELS"}="on"; 219$n_rejoinchannels=1; 220&docommand("^alias rejoinchan set rejoinchannels"); 221 222sub set_reconnect { 223 $set{'RECONNECT'}="on", $n_reconnect=1 if $_[0] =~ /^on$/i; 224 $set{'RECONNECT'}="off", $n_reconnect=0 if $_[0] =~ /^off$/i; 225} 226&addset("reconnect"); 227$set{"RECONNECT"}="on"; 228$n_reconnect=1; 229&docommand("^alias reconnect set reconnect"); 230 231sub set_awayonce { 232 $set{'AWAYONCE'}="on", $n_awayonce=1 if $_[0] =~ /^on$/i; 233 $set{'AWAYONCE'}="off", $n_awayonce=0 if $_[0] =~ /^off$/i; 234 %n_awayonce=(); 235} 236&addset("awayonce"); 237$set{"AWAYONCE"}="on"; 238$n_awayonce=1; 239&docommand("^alias awayonce set awayonce"); 240 241sub set_slowserver { 242 $set{'SLOWSERVER'}="on", $n_slowserver=1 if $_[0] =~ /^on$/i; 243 $set{'SLOWSERVER'}="off", $n_slowserver=0 if $_[0] =~ /^off$/i; 244} 245&addset("slowserver"); 246$set{"SLOWSERVER"}="off"; 247$n_slowserver=0; 248&docommand("^alias ss set slowserver"); 249 250sub set_wallv { 251 $set{"WALLV"}="on", $n_wallv=1 if $_[0] =~ /^on$/i; 252 $set{"WALLV"}="off", $n_wallv=0 if $_[0] =~ /^off$/i; 253} 254&addset("wallv"); 255$set{"WALLV"}="off"; 256$n_wallv=0; 257&docommand("^alias wallv set wallv"); 258 259sub set_quitmsg { 260 $n_quitmsg=$set{"QUITMSG"}=$_[0]; 261} 262&addset("quitmsg"); 263$set{"QUITMSG"}=$n_quitmsg=''; 264&docommand("^alias setquit set quitmsg"); 265 266sub set_autoop { 267 $set{"AUTOOP"}="off", $n_autoops=0 if $_[0] =~ /^(off|none)$/i; 268 $set{"AUTOOP"}="on", $n_autoops=1 if $_[0] =~ /^(on|all)$/i; 269 $set{"AUTOOP"}="oppass", $n_autoops=2 if $_[0] =~ /^op(pass)?$/i; 270} 271&addset("autoop"); 272$set{"AUTOOP"}="on"; 273$n_autoops=1; 274&docommand("^alias autoop set autoop"); 275 276sub set_opdelay { 277 $set{"OPDELAY"}=$n_opdelay=$_[0] if $_[0] =~ /^\d+$/; 278} 279&addset("opdelay"); 280$set{"OPDELAY"}="on"; 281$n_opdelay=5; 282&docommand("^alias delay set opdelay"); 283 284sub set_oppass { 285 $set{"OPPASS"}=$_[0]; 286} 287&addset("oppass"); 288$set{"OPPASS"}=""; 289&docommand("^alias oppass set oppass"); 290 291# ignores 292 293sub cmd_ig { 294 &docommand("ignore $args"), return if (!$args || $args =~ /^-/); 295 &getarg; 296 if ($newarg =~ /\@/) { 297 $n_lastignore=$newarg; 298 &docommand("ignore $newarg"); 299 } else { 300 &userhost($newarg, "\$host=&n_hostpat(\$host); \$user =~ s/^\\~//; \$n_lastignore=\"*\$user\\\@\$host\"; &docommand(\"ignore *\$user\\\@\$host\");"); 301 } 302} 303&addcmd("ig"); 304 305sub cmd_sig { 306 &getarg; 307 &userhost($newarg, "\$host=&n_hostpat(\$host); \$n_lastignore=\"*\\\@\$host\"; &docommand(\"ignore *\\\@\$host\");"); 308} 309&addcmd("sig"); 310 311sub cmd_unig { 312 &getarg; 313 if ($newarg eq '') { 314 &docommand("ignore -$n_lastignore") if $n_lastignore ne ''; 315 } elsif ($newarg =~ /\@/) { 316 &docommand("ignore -$newarg"); 317 } else { 318 &userhost($newarg, "\$host=&n_hostpat(\$host); \$user =~ s/^\\~//; &docommand(\"ignore -*\$user\\\@\$host\");"); 319 } 320} 321&addcmd("unig"); 322 323# bans and unbans 324 325sub n_hostpat { 326 if ($_[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { 327 return "${1}.${2}.${3}.*"; 328 } elsif ($_[0] =~ /^([^. \t]+)\.([^. \t]+)\.(.*)$/) { 329 return "*.${2}.${3}"; 330 } else { 331 return $_[0]; 332 } 333} 334 335sub cmd_kb { 336 &getarg; 337 local($why)=($args); 338 $why="game over, man. game over." unless $why; 339 &tell("*\cb0\cb* Must specify a nick to kickban"), return unless $newarg; 340 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 341 &userhost($newarg, "\$host=&n_hostpat(\$host); \$user =~ s/^\\~//; 342&sl(\"MODE $talkchannel -o+b $newarg *!*\$user\\\@\$host\"); 343&sl(\"KICK $talkchannel $newarg :$why\");"); 344} 345&addcmd("kb"); 346 347sub cmd_ksb { 348 &getarg; 349 local($why)=($args); 350 $why="d0rks suck big m00se ballZ" unless $why; 351 &tell("*\cb0\cb* Must specify a nick to kicksiteban"), return unless $newarg; 352 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 353 &userhost($newarg, "\$host=&n_hostpat(\$host); 354&sl(\"MODE $talkchannel -o+b $newarg *!*\\\@\$host\"); 355&sl(\"KICK $talkchannel $newarg :$why\");"); 356} 357&addcmd("ksb"); 358 359sub cmd_ban { 360 &tell("*\cb0\cb* Must specify a nick to ban"), return unless $args; 361 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 362 while (&getarg, $newarg ne '') { 363 &userhost($newarg, "\$host=&n_hostpat(\$host); \$user =~ s/^\\~//; 364 &sl(\"MODE $talkchannel +b *!*\$user\\\@\$host\");"); 365 } 366} 367&addcmd("ban"); 368 369sub cmd_sban { 370 &getarg; 371 &tell("*\cb0\cb* Must specify a nick to site ban"), return unless $newarg; 372 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 373 &userhost($newarg, "\$host=&n_hostpat(\$host); 374&sl(\"MODE $talkchannel +b *!*\\\@\$host\");"); 375} 376&addcmd("sban"); 377 378sub n_unbans { 379 local($n, $l)=('0', ''); 380 foreach (@n0thing_banlist) { 381 if ($n<4) { 382 $l.=" ".$_; 383 $n++; 384 } else { 385 &sl("MODE $n0thing_channel -bbbb $l"); 386 $l=$_; 387 $n=1; 388 } 389 } 390 &sl("MODE $n0thing_channel -".("b" x $n)." $l"); 391} 392 393sub cmd_sb { 394 &dosplat; 395 &getarg; 396 $newarg=$talkchannel unless $newarg; 397 return unless $newarg; 398 $n_svbanchannel=$newarg; 399 @n_svbanlist=(); 400 $n_nxbannb=1; 401 &sl("MODE $newarg b"); 402} 403&addcmd("sb"); 404 405sub hook_nbbans { 406 local($c, $theban, $by)=((split(/ +/, $_[0]))[1, 2, 3]); 407 if ($n_nxbannb && &eq($c, $n_svbanchannel)) { 408 push(@n_svbanlist, $theban); 409 &tell("*\cbb\cb* $c $n_nxbannb: $theban $by"); 410 $silent=1; 411 $n_nxbannb++; 412 } 413} 414&addhook("367", "nbbans"); 415 416sub hook_endofbans { 417 $n_nxbannb=0; 418} 419&addhook("368", "endofbans"); 420 421sub cmd_cb { 422 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 423 &addhook("367", "onecbban"); 424 &addhook("368", "donebans"); 425 @n0thing_banlist=(); 426 $n0thing_channel=$talkchannel; 427 &sl("MODE $talkchannel b"); 428} 429&addcmd("cb"); 430 431sub hook_onecbban { 432 local($theban)=((split(/ +/, $_[0]))[2]); 433 push(@n0thing_banlist, $theban); 434 $silent=1; 435} 436 437sub hook_donebans { 438 &remhook("367", "onecbban"); 439 &remhook("367", "oneubban"); 440 &remhook("368", "donebans"); 441 &n_unbans; 442} 443 444sub cmd_unban { 445 &getarg; 446 &tell("*\cb0\cb* Must specify a nick or address to unban"), return 447 unless $newarg; 448 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 449 if ($newarg =~ /^\d+$/) { 450 $n0thing_channel=$talkchannel; 451 @n0thing_banlist=(); 452 while(1) { 453 $newarg--; 454 &tell("*\cb0\cb* No banlist available for $talkchannel"), return 455 unless &eq($talkchannel, $n_svbanchannel); 456 &tell("*\cb0\cb* No such ban"), return unless $n_svbanlist[$newarg]; 457 push(@n0thing_banlist, $n_svbanlist[$newarg]); 458 &getarg; 459 last unless $newarg; 460 &tell("*\cb0\cb* Cannot mix nicks and numbers"), last 461 unless $newarg =~ /^\d+$/; 462 } 463 &n_unbans; 464 } else { 465 @n0thing_banlist=(); 466 $n0thing_channel=$talkchannel; 467 if ($newarg =~ /\@/) { 468 $newarg="*!".$newarg unless $newarg =~ /\!/; 469 $n_pat=$newarg; 470 &addhook("367", "oneubban"); 471 &addhook("368", "donebans"); 472 &sl("MODE $talkchannel b"); 473 } else { 474 &userhost($newarg, "&n_dounban;"); 475 } 476 } 477} 478&addcmd("unban"); 479&docommand("^alias ub unban"); 480 481sub n_dounban { 482 $n_pat=$who."!".$user."\@".$host; 483 &addhook("368", "donebans"); 484 @n0thing_banlist=(); 485 $n0thing_channel=$talkchannel; 486 &sl("MODE $talkchannel b"); 487} 488 489sub hook_oneubban { 490 local($theban)=((split(/ +/, $_[0]))[2]); 491 local($tb0)=($theban); 492 &slashify($theban); 493 push(@n0thing_banlist, $tb0) if ($n_pat =~ /^${theban}$/i); 494 $silent=1; 495} 496 497sub cmd_fkb { 498 &getarg; 499 &tell("*\cb0\cb* Must specify a nick to filter kick ban"), return unless $newarg; 500 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 501 &userhost($newarg, "\$host=&n_hostpat(\$host); 502&sl(\"MODE $talkchannel +b *!*\\\@\$host\"); &docommand(\"fk \$host $args\");"); 503} 504&addcmd("fkb"); 505 506 507sub cmd_fk { 508 &getarg; 509 &tell("*\cb0\cb* Must specify a pattern to kick"), return unless $newarg; 510 &tell("*\cb0\cb* You're not on a channel"), return unless $talkchannel; 511 $n0thing_channel=$talkchannel; 512 $n0thing_kickpat=$newarg; 513 &slashify($n0thing_kickpat); 514 $n0thing_kickmsg=$args || "though names may change each face retains the mask it wore"; 515 &addhook("352", "dofklist"); 516 &addhook("315", "donefk"); 517 &sl("WHO $talkchannel"); 518} 519&addcmd("fk"); 520 521sub hook_dofklist { 522 local($a)=@_; 523 local($c, $c, $u, $h, $s, $n)=split(/ +/, $a); 524 (($n."!".$u."\@".$h) =~ /${n0thing_kickpat}/i) && $n ne $nick && 525 &sl("KICK $n0thing_channel $n :$n0thing_kickmsg"); 526 $silent=1; 527} 528 529sub hook_donefk { 530 &remhook("352", "dofklist"); 531 &remhook("315", "donefk"); 532} 533 534# the msg logger 535 536sub cmd_setaway { 537 &me("is away - $args - messages will be logged") if $talkchannel; 538 push(@n_savemsg, "-- set away on " . &date(time) . " -- $args"); 539 %n_awaysent=(); 540 $args="\cb\cb" if $args eq ''; 541 &sl("AWAY :$args"); 542 $n_isaway=1; 543} 544&addcmd("setaway"); 545 546sub cmd_qsetaway { 547 push(@n_savemsg, "-- set away on " . &date(time) . " -- $args"); 548 %n_awaysent=(); 549 $args="\cb\cb" if $args eq ''; 550 &sl("AWAY :$args"); 551 $n_isaway=1; 552} 553&addcmd("qsetaway"); 554 555sub hook_messages { 556 if ($n_isaway) { 557 local($sec, $min, $hour)=localtime(time); 558 local($w)=$who; 559 $min="0".$min if $min =~ /^\d$/; 560 push(@n_savemsg, ":\cb${who}\cb!${user}\@${host} (${hour}:${min}): $_[0]\n"); 561 $w =~ tr/A-Z/a-z/; 562 &sl("NOTICE $who :Your messages are being logged - n0thing.pl"), 563 $n_awaysent{$w}=1 unless $n_awaysent{$w}; 564 } 565} 566&addhook("msg", "messages"); 567 568sub hook_dmessages { 569 if ($n_isaway) { 570 local($sec, $min, $hour)=localtime(time); 571 $min="0".$min if $min =~ /^\d$/; 572 push(@n_savemsg, "=\cb".$_[0]."\cb (${hour}:${min})= ".$_[1]."\n"); 573 } 574} 575&addhook("dcc_chat", "dmessages"); 576 577sub cmd_setback { 578 $n_isaway=''; 579 &sl("AWAY"); 580 foreach (@n_savemsg) { 581 &tell($_); 582 } 583 if ($#n_savemsg>0) { 584 &getuserline("*** Forget saved messages (y/n)? ", "clear? "); 585 @n_savemsg=() if /^y/i; 586 } else { 587 @n_savemsg=(); 588 } 589} 590&addcmd("setback"); 591 592sub cmd_clearmes { 593 $n_isaway=''; 594 @n_savemsg=(); 595} 596&addcmd("clearmes"); 597 598# wallops 599 600sub cmd_wall { 601 &tell("*\cbE\cb* No text to send"), return unless $args; 602 &tell("*\cbE\cb* You're not on a channel"), return unless $talkchannel; 603 $wallop_text=$args; 604 $wallop_channel=$talkchannel; 605 &addhook("353", "wallopnames"); 606 &sl("NAMES $talkchannel"); 607} 608&addcmd("wall"); 609 610sub hook_wallopnames { 611 local($wallop, $n, $s, @wallop)=("", 0, 0, split(/ +/, $_[0])); 612 shift @wallop; shift @wallop; shift @wallop; 613 $wallop[0] =~ s/^://; 614 foreach (@wallop) { 615 $wallop.=$_.",", $n++ if s/^\@// || ($n_wallv && s/^\+//) || &eq($_, $nick); 616 if ($n>=9) { 617 $wallop =~ s/,$//; 618 &sl("NOTICE $wallop :\cb[WallOp/$wallop_channel]\cb $wallop_text"); 619 $n=0; 620 $s=1; 621 $wallop=''; 622 } 623 } 624 if ($wallop eq '' && !$s) { 625 &tell("*\cbE\cb* No ops to wallop"); 626 } elsif ($wallop ne '') { 627 $wallop =~ s/,$//; 628 &sl("NOTICE $wallop :\cb[WallOp/$wallop_channel]\cb $wallop_text"); 629 } 630 &remhook("353", "wallopnames"); 631 $silent=1; 632} 633 634 635# the autoop list, with fully-featured delayed and grouped auto-ops 636 637sub n_addwaitop { 638 local($nck, $channel)=@_; 639 if ($n_opdelay) { 640 local($n)=($nck); 641 $channel =~ tr/A-Z/a-z/; 642 $n =~ s/(\W)/\\$1/g; 643 if ($n_waitops{$channel} !~ /:${n}:/i) { 644 $n_waitops{$channel} || ($n_waitops{$channel}=":"); 645 $n_waitops{$channel}.=$nck.":"; 646 } 647 unless ($n_timerdue) { 648 $n_timerdue=1; 649 &timer($n_opdelay, "&n_doautoops"); 650 } 651 } else { 652 &sl("MODE $channel +o $nck"); 653 } 654} 655 656sub n_remwaitop { 657 local($nck, $channel)=@_; 658 $channel =~ tr/A-Z/a-z/; 659 $nck =~ s/(\W)/\\$1/g; 660 $n_waitops{$channel} =~ s/:${nck}:/:/gi; 661 delete $n_waitops{$channel} if $n_waitops{$channel} eq ":"; 662} 663 664sub n_doautoops { 665 local($l); 666 foreach $c (keys(%n_waitops)) { 667 if ($n_waitops{$c} ne ":" && $n_waitops{$c}) { 668 $l=$n_waitops{$c}; 669 $l =~ s/^://; 670 $l =~ s/:$//; 671 $l =~ tr/:/ /; 672 &docommand("o ".$c." ".$l); 673 } 674 delete $n_waitops{$c}; 675 } 676 $n_timerdue=''; 677} 678 679sub hook_n_nickchange { 680 local($oldnick)=$who; 681 $oldnick =~ s/(\W)/\\$1/g; 682 foreach $c (keys(%n_waitops)) { 683 $n_waitops{$c} =~ s/:${oldnick}:/:$_[0]:/gi; 684 } 685} 686&addhook("nick", "n_nickchange"); 687 688sub hook_n_parted { 689 &n_remwaitop($who, $_[0]); 690} 691&addhook("leave", "n_parted"); 692 693sub hook_n_quitted { 694 local($w)=$who; 695 $w =~ s/(\W)/\\$1/g; 696 foreach $c (keys(%n_waitops)) { 697 $n_waitops{$c} =~ s/:${w}:/:/gi; 698 delete $n_waitops{$c} if $n_waitops{$c} eq ":"; 699 } 700} 701&addhook("signoff", "n_quitted"); 702 703sub hook_n_modechange { 704# we only deal with +o, +oo and the like; the worst that can happen 705# is that we op someone again 706 local ($l)=$_[1]; 707 return unless $_[0] =~ /^[\#\&\+]/; 708 return unless $l =~ s/^\+o+\s+//; 709 foreach $n (split(/ /, $l)) { 710 &n_remwaitop($n, $_[0]); 711 } 712} 713&addhook("mode", "n_modechange"); 714 715sub slashify { 716 $_[0] =~ s/([^\\])\./$1\\./g; 717 $_[0] =~ s/\*/\.\*/g; 718 $_[0] =~ s/([^\.\*\?\\\w])/\\$1/g; 719 $_[0] =~ tr/?/./; 720} 721 722# format of the entries in @n_autooplist : 723# asked:channel:nick!user@host in regexp format; asked is '.' or '1', 724# channel is '.*' or a #channel name 725 726sub autoopped { 727 local($nuh, $chan, $asked)=@_; 728# chan = what chan for, $asked = whether it was asked 729 local($p); 730 foreach $p (@n_autooplist) { 731 return 1 if ($asked.":".$chan.":".$nuh) =~ /^${p}$/i; 732 } 733 return ''; 734} 735 736sub addtoops { 737 local($chan, $auto)=@_; 738 if (&autoopped($who."!".$user."\@".$host, $chan, 1)) { 739 &tell("*\cb0\cb* $who is already on your list"); 740 } else { 741 $host=&n_hostpat($host); 742 $user =~ s/^\~//; 743 local($pat)=("*!*".$user."\@".$host); 744 &tell("*\cb0\cb* Adding $who as $pat to your autoop list for $chan"); 745 &sl("NOTICE $who :You have been added to ${nick}'s autoop list for ". 746 ($chan eq '*' ? "all channels" : "$chan")); 747 &sl("NOTICE $who :You should feel *very* honored"); 748 &slashify($pat); 749 &slashify($chan); 750 push(@n_autooplist, $auto.":".$chan.":".$pat); 751 } 752} 753 754sub cmd_addop { 755 if ($args =~ /^([01])\s+(\S+)\s+(\S+)\s*$/) { 756 local($auto, $chan, $uh)=($1, $2, $3); 757 if ($chan ne '*' && $chan !~ /^[#&]/) { 758 &tell("*\cbE\cb* Invalid channel - use '*' or a #channel name"); 759 return; 760 } 761 $chan =~ s/\'//g; 762 $uh="*!".$uh if $uh =~ /\@/ && $uh !~ /\!/; 763 $auto=($auto==0 ? "1" : "."); 764 if ($uh =~ /\!.*\@/) { 765 if (&autoopped($uh, $chan, 1)) { 766 &tell("*\cb0\cb* $uh is already on your list"); 767 return; 768 } 769 &tell("*\cb0\cb* Adding $uh to your auto-op list for $chan"); 770 &slashify($uh); 771 &slashify($chan); 772 push(@n_autooplist, $auto.":".$chan.":".$uh); 773 } else { 774 &userhost($uh, "&addtoops('$chan', '$auto');"); 775 } 776 } else { 777 &tell("*\cb0\cb* Format: /addop (0 or 1) (#chan or *) (nick or user\@host)"); 778 } 779} 780&addcmd("addop"); 781 782sub hook_joined { 783 local($c)=($_[0]); 784 $c =~ tr/A-Z/a-z/; 785 &n_addwaitop($who, $c) if ($n_autoops==1 && $haveops{$c} && 786 &autoopped($who."!".$user."\@".$host, $c, 0)); 787} 788&addhook("join", "joined"); 789 790sub hook_opbeg { 791 if ($_[1] =~ /^op$/i && $n_autoops && &eq($nick, $_[0])) { 792 local($chn, $pass)=split(/ +/, $_[2]); 793 $chn =~ tr/A-Z/a-z/; 794 &sl("MODE $chn +o $who") 795 if $haveops{$chn} && $pass eq $set{"OPPASS"} && 796 &autoopped($who."!".$user."\@".$host, $chn, 1); 797 } 798} 799&addhook("ctcp", "opbeg"); 800 801sub cmd_listop { 802 local($n, $p, $q, $c, $a, $ch)=(0); 803 &getarg; 804 $ch=$newarg || '*'; 805 &tell("*\cb0\cb* That's the people in your autoop list:"); 806 foreach $p (@n_autooplist) { 807 ($a, $c, $q)=split(/:/, $p); 808 $c =~ s/\\//g; 809 $c =~ s/\.\*/*/g; 810 next if (!&eq($c, $ch) && $c ne '*' && $ch ne '*'); 811 $n++; 812 $q =~ s/\\//g; 813 $q =~ s/\.\*/*/g; 814 &tell("*\cb0\cb* ".($a eq '.' ? "1 " : "0 ").$c." ".$q); 815 } 816 &tell("*\cb0\cb* which makes.. uhm... $n people, I think"); 817} 818&addcmd("listop"); 819 820sub rem_matches { 821 local($nuh, $ent)=@_; 822 $ent=$' if $ent =~ /:.*:/; 823 return 1 if $nuh =~ /${ent}$/i; 824 # not exactly the same as slashify 825 $nuh =~ s/\*/\.\*/g; 826 $nuh =~ s/([^\\])\.([^\*])/$1\\\\*\\.$2/g; 827 $nuh =~ s/([^\.\*\?\\\w])/\\\\*\\$1/g; 828 $nuh =~ tr/?/./; 829 return ($ent =~ /${nuh}$/i); 830} 831 832sub n_remop { 833 local($nuh)=($who."!".$user."\@".$host); 834 @n_autooplist=grep(!&rem_matches($nuh, $_), @n_autooplist); 835} 836 837sub cmd_remop { 838 &getarg; 839 if (!$newarg) { 840 &tell("*\cb0\cb* Must specify a nick or address"); 841 } elsif ($newarg =~ /[\@\*]/) { 842 # $newarg='*!'.$newarg if ($newarg !~ /\!/); 843 &tell("*\cb0\cb* Time to remove $newarg from the autoop list"); 844 @n_autooplist=grep(!&rem_matches($newarg, $_), @n_autooplist); 845 } else { 846 &tell("*\cb0\cb* Time to remove $newarg from the autoop list"); 847 &userhost($newarg, "&n_remop;"); 848 } 849} 850&addcmd("remop"); 851 852sub cmd_clearop { 853 @n_autooplist=(); 854 &tell("*\cb0\cb* Auto-op list cleared!"); 855} 856&addcmd("clearop"); 857 858# saving the settings 859 860sub cmd_sve { 861 local($p); 862 if (!open(SVE, "> ".$n_svefile)) { 863 &tell("*\cbE\cb* can't write to save file"); 864 return; 865 } 866 # old-style stuff for compatibility with old n0things 867 print SVE $n_autoops+0, "\n"; 868 print SVE ($n_autorejoin ? "1" : "0"), "\n"; 869 print SVE "\n"; # deprecated, pong reply 870 print SVE $set{"FINGER"}, "\n"; 871 print SVE join(" ", keys(%notify)), "\n"; 872 print SVE join(" ", @n_autooplist), "\n"; 873 print SVE ($n_slowserver ? "1" : "0"), "\n"; 874 print SVE $n_opdelay, "\n"; 875 print SVE $n_quitmsg, "\n"; 876 print SVE "^\n"; # deprecated, command char 877 print SVE ($n_reconnect ? "1" : "0"), "\n"; 878 # and new-style saves 879 print SVE $set{"AWAYONCE"}, "\n"; 880 print SVE $set{"REJOINCHANNELS"}, "\n"; 881 print SVE $set{"CTCP"}, "\n"; 882 print SVE $set{"PRINTCHAN"}, "\n"; 883 print SVE $set{"PRINTUH"}, "\n"; 884 print SVE $set{"SENDAHEAD"}, "\n"; 885 print SVE $set{"USERINFO"}, "\n"; 886 print SVE $set{"WALLV"}, "\n"; 887 print SVE $set{"OPPASS"}, "\n"; 888 print SVE $set{"IRCNAME"}, "\n"; 889 close SVE; 890 &tell("*\cb0\cb* save completed!"); 891} 892&addcmd("sve"); 893 894sub cmd_quit { 895 if ($args eq '') { 896 &docommand("/QUIT $n_quitmsg"); 897 } else { 898 &docommand("/QUIT $args"); 899 } 900} 901&addcmd("quit"); 902&docommand("^alias bye quit"); 903&docommand("^alias exit quit"); 904&docommand("^alias signoff quit"); 905 906# some online help 907 908sub cmd_nhelp { 909 &docommand("help n0thing".$args); 910} 911&addcmd("nhelp"); 912 913&addhelp("n0thing", "This is \cbn0thing.pl\cb for sirc, by \cborabidoo\cb 914 915For the list of n0thing.pl's general functions, type /nhelp general 916For the list of n0thing.pl's channel functions, type /nhelp channel 917For the list of n0thing.pl's file functions, type /nhelp files 918For the list of n0thing.pl's settings, type /nhelp settings 919 920Arguments between []'s are always optional. 921 922For comments, bug reports, ideas: email roger.espel.llima\@pobox.com"); 923 924&addhelp("n0thinggeneral", "List of \cbn0thing.pl\cb's functions: 925 926/a <message> sends to the last person you /msg'd 927/ver <nick> gets version info about <nick> 928/tim <nick> gets <nick>'s local time 929/setaway <reason> sets yourself away, logs messages 930/qsetaway <reason> like /setaway without doing the /me 931/setback sets yourself back, shows messages 932/clearmes erases saved messages 933/ig <nick> ignores <nick> (using a user\@host mask) 934/sig <nick> ignores <nick>'s site 935/unig [nick] unignores <nick> or undoes your last /ig 936/sve saves your settings and auto-op and notify list"); 937 938&addhelp("n0thingchannel", "List of \cbn0thing.pl\cb's channel functions: 939 940/sb [<channel>] shows ban list on a channel [current one] 941/ban <nick> [<nick>...] bans on current channel 942/sban <nick> bans the whole site on current channel 943/ub <nick>|<address> unbans on current channel 944/ub <number> [<nmbr>..] removes bans by number after a /sb 945/cb clears all bans on current channel 946/l short list of people on the current channel 947/pj part and rejoin current channel 948/open [<channel>] removes weird modes on the channel [current one] 949/kb <nick> [<reason>] kicks and bans 950/ksb <nick> [<reason>] kicks and site-bans 951/fk <filter> [<reasn>] kicks all users matching the filter 952/fkb <nick> [<reasn>] site-bans and kicks all users from the same site 953/wall <msg> send a message to the current channel's ops"); 954 955&addhelp("n0thingsettings", 956"List of \cbn0thing.pl\cb's SET variables: 957autorejoin [on|off] toggles auto-rejoin on kick 958rejoinchannels [on|off] toggles rejoining channels on reconnect 959reconnect [on|off] toggles auto-reconnect 960awayonce [on|off] toggles hiding duplicate away messages 961slowserver [on|off] toggles avoiding userhost on notify 962wallv [on|off] toggles sending walls to +v people 963autoop [on|oppass|off] toggle autoops (oppass requires a ctcp op w/ the 964 channel name and a password) 965oppass <password> toggles your opbeg password 966quitmsg <message> sets your default /quit message 967 968List of \cbn0thing.pl\cb's setting-related commands: 969/addop <aop> #chn <user> adds to op list; aop is 0 or 1; #chn can be * 970/remop <nick>|<address> removes user from your auto-op list 971/clearop clears your auto-op list 972/listop [#chn] lists your auto-op list [for channel #chn] 973/delay sets your auto-op delay 974/sve saves your settings and auto-op and notify list"); 975 976&addhelp("n0thingfiles", "List of \cbn0thing.pl\cb's file-oriented functions: 977/dc [<nick>] starts a dcc chat [last offered] 978/dg [<nick>] [<file>] gets a file via dcc [last offered] 979/ds <nick> <file> sends a file via dcc 980/cdc <nick> closes a /dcc chat 981/cds <nick> closes a /dcc send connection 982/cdg <nick> closes a /dcc get connection 983/rdc <nick1> <nick2> renames a /dcc chat 984/ex <command> \"shortcut\" for /system 985/ls [<args>] lists files 986/cat <files> shows files 987/rm <files> deletes files 988/ps <options> lists processes 989/mail reads your mail (you'll get disconnected from the 990 server if this takes more than a few minutes; exit 991 with 'q')"); 992 993# reading the saved settings 994 995if (open(NOTHING, "< ".$n_svefile)) { 996 local($n, $l); 997 998 chop($l=<NOTHING>); 999 &doset("AUTOOP", ($l ? "on" : "off")); 1000 1001 chop($l=<NOTHING>); 1002 &doset("AUTOREJOIN", ($l ? "on" : "off")); 1003 1004 <NOTHING>; 1005 1006 chop($l=<NOTHING>); 1007 &doset("FINGER", $l) if $l ne ''; 1008 1009 chop($l=<NOTHING>); 1010 %notify=(); 1011 foreach $n (split(' ', $l)) { 1012 &docommand("^NOTIFY ".$n); 1013 } 1014 1015 chop($l=<NOTHING>); 1016 @n_autooplist=split(' ', $l); 1017 foreach (@n_autooplist) { 1018 $_=".:.*:".$_ unless /:.*:/; 1019 } 1020 1021 chop($l=<NOTHING>); 1022 &doset("SLOWSERVER", ($l ? "on" : "off")); 1023 1024 chop($l=<NOTHING>); 1025 $l=5 if $l !~ /^\d+$/; 1026 &doset("OPDELAY", $l); 1027 1028 chop($l=<NOTHING>); 1029 &doset("QUITMSG", $l); 1030 1031 <NOTHING>; 1032 1033 chop($l=<NOTHING>); 1034 $l=1 unless defined $l; 1035 &doset("RECONNECT", ($l ? "on" : "off")); 1036 1037 chop($l=<NOTHING>); 1038 &doset("AWAYONCE", $l) if $l; 1039 1040 chop($l=<NOTHING>); 1041 &doset("REJOINCHANNELS", $l) if $l; 1042 1043 chop($l=<NOTHING>); 1044 &doset("CTCP", $l) if $l; 1045 1046 chop($l=<NOTHING>); 1047 &doset("PRINTCHAN", $l) if $l; 1048 1049 chop($l=<NOTHING>); 1050 &doset("PRINTUH", $l) if $l; 1051 1052 chop($l=<NOTHING>); 1053 &doset("SENDAHEAD", $l) if $l; 1054 1055 chop($l=<NOTHING>); 1056 &doset("USERINFO", $l) if $l; 1057 1058 chop($l=<NOTHING>); 1059 &doset("WALLV", $l) if $l; 1060 1061 chop($l=<NOTHING>); 1062 &doset("OPPASS", $l) if $l; 1063 1064 chop($l=<NOTHING>); 1065 &doset("IRCNAME", $l) if $l; 1066 1067 close(NOTHING); 1068} 1069 1070&print("*\cb0\cb* \cborabidoo\cb's *\cvn0thing.pl\cv* for sirc loaded, type /nhelp for help"); 1071 1072