2 # UserDCC.pl: User Commands, DCC CHAT.
4 # Version: v0.2 (20010119)
5 # Created: 20000707 (from UserExtra.pl)
8 if (&IsParam("useStrict")) { use strict; }
16 if ($message =~ /^(exit|quit)$/i) {
17 # do ircII clients support remote close? if so, cool!
18 &status("userDCC: quit called. FIXME");
20 &status("userDCC: after dcc_close!");
26 if ($message =~ /^who$/) {
27 my $count = scalar(keys %{$dcc{'CHAT'}});
28 my $dccCHAT = $message;
30 &pSReply("Start of who ($count users).");
31 foreach (keys %{$dcc{'CHAT'}}) {
34 &pSReply("End of who.");
39 ### for those users with enough flags.
42 if ($message =~ /^4op(\s+($mask{chan}))?$/i) {
43 return unless (&hasFlag("o"));
52 if (!$channels{$chan}{'o'}{$ident}) {
53 &msg($who, "i don't have ops on $chan to do that.");
57 # on non-4mode(<4) servers, this may be exploited.
58 if ($channels{$chan}{'o'}{$who}) {
59 rawout("MODE $chan -o+o-o+o". (" $who" x 4));
61 rawout("MODE $chan +o-o+o-o". (" $who" x 4));
68 if ($message =~ /^backlog(\s+(.*))?$/i) {
69 return unless (&hasFlag("o"));
70 return unless (&hasParam("backlog"));
72 my $max = $param{'backlog'};
77 } elsif ($num !~ /^\d+/) {
78 &msg($who, "error: argument is not positive integer.");
80 } elsif ($num > $max or $num < 0) {
81 &msg($who, "error: argument is out of range (max $max).");
85 &msg($who, "Start of backlog...");
87 sleep 1 if ($_ % 4 == 0 and $_ != 0);
88 $conn->privmsg($who, "[".($_+1)."]: $backlog[$max-$num+$_]");
90 &msg($who, "End of backlog.");
96 if ($message =~ /^dumpvars$/i) {
97 return unless (&hasFlag("o"));
98 return unless (&IsParam("dumpvars"));
100 &status("Dumping all variables...");
107 if ($message =~ /^kick(\s+(\S+)(\s+(\S+))?)?/) {
108 return unless (&hasFlag("o"));
109 my ($nick,$chan) = (lc $2,lc $4);
116 if (&validChan($chan) == 0) {
117 &msg($who,"error: invalid channel \002$chan\002");
121 if (&IsNickInChan($nick,$chan) == 0) {
122 &msg($who,"$nick is not in $chan.");
132 if ($message =~ /^mode(\s+(.*))?$/) {
133 return unless (&hasFlag("n"));
134 my ($chan,$mode) = split /\s+/,$2,2;
141 if (&validChan($chan) == 0) {
142 &msg($who,"error: invalid channel \002$chan\002");
146 if (!$channels{$chan}{o}{$ident}) {
147 &msg($who,"error: don't have ops on \002$chan\002");
157 if ($message =~ /^part(\s+(\S+))?$/i) {
158 return unless (&hasFlag("o"));
161 if ($jchan !~ /^$mask{chan}$/) {
162 &msg($who, "error, invalid chan.");
167 if (!&validChan($jchan)) {
168 &msg($who, "error, I'm not on that chan.");
172 &msg($jchan, "Leaving. (courtesy of $who).");
177 # lobotomy. sometimes we want the bot to be _QUIET_.
178 if ($message =~ /^(lobotomy|bequiet)$/i) {
179 return unless (&hasFlag("o"));
182 &performReply("i'm already lobotomized");
184 &performReply("i have been lobotomized");
192 if ($message =~ /^(unlobotomy|benoisy)$/i) {
193 return unless (&hasFlag("o"));
196 &performReply("i have been unlobotomized, woohoo");
198 delete $cache{lobotomy};
199 # undef $cache{lobotomy}; # ??
201 &performReply("i'm not lobotomized");
208 if ($message =~ /^op(\s+(.*))?$/i) {
209 return unless (&hasFlag("o"));
214 if ($opee =~ /^(\S+)\s+(\S+)$/) {
217 if (!&validChan($2)) {
218 &msg($who,"error: invalid chan ($2).");
222 &msg($who,"error: invalid params.");
226 @chans = keys %channels;
232 next unless (&IsNickInChan($opee,$_));
234 if ($channels{$_}{'o'}{$opee}) {
235 &pSReply("op: $opee already has ops on $_");
240 &pSReply("opping $opee on $_");
245 &pSReply("op: opped on all possible channels.");
247 &DEBUG("op: found => '$found'.");
248 &DEBUG("op: op => '$op'.");
255 if ($message =~ /^deop(\s+(.*))?$/i) {
256 return unless (&hasFlag("o"));
261 if ($opee =~ /^(\S+)\s+(\S+)$/) {
264 if (!&validChan($2)) {
265 &msg($who,"error: invalid chan ($2).");
269 &msg($who,"error: invalid params.");
273 @chans = keys %channels;
279 next unless (&IsNickInChan($opee,$_));
281 if (!exists $channels{$_}{'o'}{$opee}) {
282 &status("deop: $opee already has no ops on $_");
287 &status("deopping $opee on $_ at ${who}'s request");
292 &status("deop: deopped on all possible channels.");
294 &DEBUG("deop: found => '$found'.");
295 &DEBUG("deop: op => '$op'.");
302 if ($message =~ s/^say\s+(\S+)\s+(.*)//) {
303 return unless (&hasFlag("o"));
304 my ($chan,$msg) = (lc $1, $2);
305 &DEBUG("chan => '$1', msg => '$msg'.");
307 if (&validChan($chan)) {
310 &msg($who,"i'm not on \002$1\002, sorry.");
316 if ($message =~ /^die$/) {
317 return unless (&hasFlag("n"));
321 &status("Dying by $who\'s request");
325 # global factoid substitution.
326 if ($message =~ m|^s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
327 my ($delim,$op,$np) = ($1, $2, $3);
328 return unless (&hasFlag("n"));
329 ### TODO: support flags to do full-on global.
332 if ($np =~ /$delim/) {
333 &performReply("looks like you used the delimiter too many times. You may want to use a different delimiter, like ':' or '#'.");
337 ### TODO: fix up $op to support mysql/pgsql/dbm(perl)
338 ### TODO: => add db/sql specific function to fix this.
339 my @list = &searchTable("factoids", "factoid_key",
340 "factoid_value", $op);
343 &performReply("Expression didn't match anything.");
347 if (scalar @list > 100) {
348 &performReply("regex found more than 100 matches... not doing.");
352 &status("gsubst: going to alter ".scalar(@list)." factoids.");
353 &performReply("going to alter ".scalar(@list)." factoids.");
359 next if (&IsLocked($faqtoid) == 1);
360 my $result = &getFactoid($faqtoid);
362 &DEBUG("was($faqtoid) => '$was'.");
365 # we could support global local (once off).
366 if ($result =~ s/\Q$op/$np/gi) {
367 if (length $result > $param{'maxDataSize'}) {
368 &performReply("that's too long (or was long)");
371 &setFactInfo($faqtoid, "factoid_value", $result);
372 &status("update: '$faqtoid' =is=> '$result'; was '$was'");
374 &WARN("subst: that's weird... thought we found the string ($op) in '$faqtoid'.");
380 &ERROR("Some warnings/errors?");
383 &performReply("Ok... did s/$op/$np/ for ".
384 (scalar(@list) - $error)." factoids");
390 if ($message =~ /^jump(\s+(\S+))?$/i) {
391 return unless (&hasFlag("n"));
399 if ($2 =~ /^(\S+)(:(\d+))?$/) {
403 &msg($who,"invalid format.");
407 &status("jumping servers... $server...");
408 &rawout("QUIT :jumping to $server");
410 if (&irc($server,$port) == 0) {
416 if ($message =~ /^reload$/i) {
417 return unless (&hasFlag("n"));
419 &status("USER reload $who");
420 &pSReply("reloading...");
422 &pSReply("reloaded.");
428 if ($message =~ /^rehash$/) {
429 return unless (&hasFlag("n"));
431 &msg($who,"rehashing...");
433 &status("USER rehash $who");
434 &msg($who,"rehashed");
440 ##### USER//CHAN SPECIFIC CONFIGURATION COMMANDS
443 if ($message =~ /^chaninfo(\s+(.*))?$/) {
444 my @args = split /[\s\t]+/, $2; # hrm.
446 if (scalar @args != 1) {
451 if (!exists $chanconf{$args[0]}) {
452 &pSReply("no such channel $args[0]");
456 &pSReply("showing channel conf.");
457 foreach (sort keys %{ $chanconf{$args[0]} }) {
458 &pSReply("$chan: $_ => $chanconf{$args[0]}{$_}");
460 &pSReply("End of chaninfo.");
466 if ($message =~ /^(chanset|\+chan)(\s+(.*?))?$/) {
471 if (!defined $args) {
477 while ($args =~ s/^($mask{chan})\s*//) {
481 if (!scalar @chans) {
482 push(@chans, "_default");
486 my($what,$val) = split /[\s\t]+/, $args, 2;
488 ### TODO: "cannot set values without +m".
489 return unless (&hasFlag("n"));
492 if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) {
493 &pSReply("Showing $what values on all channels...");
496 foreach (keys %chanconf) {
497 my $val = $chanconf{$_}{$what} || "NOT-SET";
501 foreach (keys %vals) {
502 &pSReply(" $what = $_: ".join(' ', keys %{ $vals{$_} } ) );
505 &pSReply("End of list.");
510 ### TODO: move to UserDCC again.
511 if ($cmd eq "chanset" and !defined $what) {
512 &DEBUG("showing channel conf.");
514 foreach $chan ($chan, "_default") {
515 &pSReply("chan: $chan");
516 ### TODO: merge 2 or 3 per line.
519 foreach (sort keys %{ $chanconf{$chan} }) {
520 my $newstr = join(', ', @items);
521 if (length $newstr > 60) {
526 push(@items, "$_ => $chanconf{$chan}{$_}");
528 &pSReply(" $str") if (@items);
534 &chanSet($cmd, $_, $what, $val);
540 if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) {
541 return unless (&hasFlag("n"));
545 if (!defined $args) {
552 if ($args =~ s/^(\-)?($mask{chan})\s*//) {
554 $delete = ($1) ? 1 : 0;
555 &DEBUG("chan => $chan.");
557 &VERB("no chan arg; setting to default.",2);
562 if (!exists $chanconf{$chan}) {
563 &pSReply("no such channel $chan");
569 if (!&getChanConf($args,$chan)) {
570 &pSReply("$args does not exist for $chan");
574 my @chans = &ChanConfList($args);
575 &DEBUG("scalar chans => ".scalar(@chans) );
576 if (scalar @chans == 1 and $chans[0] eq "_default" and !$no_chan) {
577 &psReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans.");
579 my $val = $chanconf{$_}{_default};
580 foreach (keys %chanconf) {
581 $chanconf{$_}{$args} = $val;
583 delete $chanconf{_default}{$args};
588 if ($no_chan and !exists($chanconf{_default}{$args})) {
589 &pSReply("ok, $args for _default does not exist, removing from all chans.");
591 foreach (keys %chanconf) {
592 next unless (exists $chanconf{$_}{$args});
593 &DEBUG("delete chanconf{$_}{$args};");
594 delete $chanconf{$_}{$args};
600 &pSReply("Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})");
601 delete $chanconf{$chan}{$args};
607 &pSReply("Deleting channel $chan for sure!");
608 $utime_chanfile = time();
612 &pSReply("Leaving $chan...");
614 delete $chanconf{$chan};
616 &pSReply("Prefix channel with '-' to delete for sure.");
622 if ($message =~ /^newpass(\s+(.*))?$/) {
623 my(@args) = split /[\s\t]+/, $2 || '';
625 if (scalar @args != 1) {
630 my $u = &getUser($who);
631 my $crypt = &mkcrypt($args[0]);
633 &pSReply("Set your passwd to '$crypt'");
634 $users{$u}{PASS} = $crypt;
636 $utime_userfile = time();
642 if ($message =~ /^chpass(\s+(.*))?$/) {
643 my(@args) = split /[\s\t]+/, $2 || '';
650 if (!&IsUser($args[0])) {
651 &pSReply("user $args[0] is not valid.");
655 my $u = &getUser($args[0]);
657 &pSReply("Internal error, u = NULL.");
661 if (scalar @args == 1) { # del pass.
662 if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
663 &pSReply("cannto remove passwd of others.");
667 if (!exists $users{$u}{PASS}) {
668 &pSReply("$u does not have pass set anyway.");
672 &pSReply("Deleted pass from $u.");
674 $utime_userfile = time();
677 delete $users{$u}{PASS};
682 my $crypt = &mkcrypt($args[1]);
683 &pSReply("Set $u's passwd to '$crypt'");
684 $users{$u}{PASS} = $crypt;
686 $utime_userfile = time();
692 if ($message =~ /^chattr(\s+(.*))?$/) {
693 my(@args) = split /[\s\t]+/, $2 || '';
701 if ($args[0] =~ /^$mask{nick}$/i) { # <nick>
702 $user = &getUser($args[0]);
705 $user = &getUser($who);
706 &DEBUG("user $who... nope.") unless (defined $user);
707 $user = &getUser($verifyUser);
711 if (!defined $user) {
712 &pSReply("user $user does not exist.");
716 my $flags = $users{$user}{FLAGS};
717 if (!defined $chflag) {
718 &pSReply("Flags for $user: $flags");
722 &DEBUG("who => $who");
723 &DEBUG("verifyUser => $verifyUser");
724 if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
725 &pSReply("cannto change attributes of others.");
731 foreach (split //, $chflag) {
732 if ($_ eq "+") { $state = 1; next; }
733 if ($_ eq "-") { $state = 0; next; }
735 if (!defined $state) {
736 &pSReply("no initial + or - was found in attr.");
741 next if ($flags =~ /\Q$_\E/);
744 if (&IsParam("owner")
745 and $param{owner} =~ /^\Q$user\E$/i
746 and $flags =~ /[nmo]/
748 &pSReply("not removing flag $_ for $user.");
751 next unless ($flags =~ s/\Q$_\E//);
758 $utime_userfile = time();
760 &pSReply("Current flags: $flags");
761 $users{$user}{FLAGS} = $flags;
763 &pSReply("No flags changed: $flags");
769 if ($message =~ /^chnick(\s+(.*))?$/) {
770 my(@args) = split /[\s\t]+/, $2 || '';
772 if ($who eq "_default") {
773 &WARN("$who or verifyuser tried to run chnick.");
777 if (!scalar @args or scalar @args > 2) {
782 if (scalar @args == 1) { # 1
783 $user = &getUser($who);
784 &DEBUG("nope, not $who.") unless (defined $user);
785 $user ||= &getUser($verifyUser);
788 $user = &getUser($args[0]);
792 if (!defined $user) {
793 &pSReply("user $who or $args[0] does not exist.");
797 if ($user =~ /^\Q$chnick\E$/i) {
798 &pSReply("user == chnick. why should I do that?");
802 if (&getUser($chnick)) {
803 &pSReply("user $chnick is already used!");
807 if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
808 &pSReply("cannto change nick of others.");
809 return "REPLY" if ($who eq "_default");
813 foreach (keys %{ $users{$user} }) {
814 $users{$chnick}{$_} = $users{$user}{$_};
815 delete $users{$user}{$_};
817 undef $users{$user}; # ???
819 $utime_userfile = time();
822 &pSReply("Changed '$user' to '$chnick' successfully.");
827 if ($message =~ /^([-+])host(\s+(.*))?$/) {
829 my(@args) = split /[\s\t]+/, $3 || '';
830 my $state = ($1 eq "+") ? 1 : 0;
837 if ($who eq "_default") {
838 &WARN("$who or verifyuser tried to run $cmd.");
843 if ($args[0] =~ /^$mask{nick}$/i) { # <nick>
844 return unless (&hasFlag("n"));
845 $user = &getUser($args[0]);
848 # who or verifyUser. FIXME!!!
849 $user = &getUser($who);
853 if (!defined $user) {
854 &pSReply("user $user does not exist.");
858 if (!defined $mask) {
860 &pSReply("Hostmasks for $user: $users{$user}{HOSTS}");
865 if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
866 &pSReply("cannto change masks of others.");
870 if ($mask !~ /^$mask{nuh}$/) {
871 &pSReply("error: mask ($mask) is not a real hostmask.");
875 my $count = scalar keys %{ $users{$user}{HOSTS} };
878 if (exists $users{$user}{HOSTS}{$mask}) {
879 &pSReply("mask $mask already exists.");
883 ### TODO: override support.
884 $users{$user}{HOSTS}{$mask} = 1;
886 &pSReply("Added $mask to list of masks.");
890 if (!exists $users{$user}{HOSTS}{$mask}) {
891 &pSReply("mask $mask does not exist.");
895 ### TODO: wildcard support. ?
896 delete $users{$user}{HOSTS}{$mask};
898 if (scalar keys %{ $users{$user}{HOSTS} } != $count) {
899 &pSReply("Removed $mask from list of masks.");
901 &pSReply("error: could not find $mask in list of masks.");
906 $utime_userfile = time();
912 if ($message =~ /^([-+])ban(\s+(.*))?$/) {
915 my(@args) = split /[\s\t]+/, $3 || '';
916 my $state = ($1 eq "+") ? 1 : 0;
923 my($mask,$chan,$time,$reason);
925 if ($flatarg =~ s/^($mask{nuh})\s*//) {
928 &DEBUG("arg does not contain nuh mask?");
931 if ($flatarg =~ s/^($mask{chan})\s*//) {
934 $chan = "*"; # _default instead?
937 if ($state == 0) { # delete.
938 my @c = &banDel($mask);
945 &pSReply("Removed $mask from chans: @c");
947 &pSReply("$mask was not found in ban list.");
958 if ($flatarg =~ s/^(\d+)\s*//) {
960 &DEBUG("time = $time.");
962 &pSReply("error: time cannot be negatime?");
969 if ($flatarg =~ s/^(.*)$//) { # need length?
973 if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
974 &pSReply("cannto change masks of others.");
978 if ($mask !~ /^$mask{nuh}$/) {
979 &pSReply("error: mask ($mask) is not a real hostmask.");
983 if ( &banAdd($mask,$chan,$time,$reason) == 2) {
984 &pSReply("ban already exists; overwriting.");
986 &pSReply("Added $mask for $chan (time => $time, reason => $reason)");
991 if ($message =~ /^whois(\s+(.*))?$/) {
999 my $user = &getUser($arg);
1000 if (!defined $user) {
1001 &pSReply("whois: user $user does not exist.");
1005 ### TODO: better (eggdrop-like) output.
1006 &pSReply("user: $user");
1007 foreach (keys %{ $users{$user} }) {
1008 my $ref = ref $users{$user}{$_};
1010 if ($ref eq "HASH") {
1012 ### DOES NOT WORK???
1013 foreach (keys %{ $users{$user}{$type} }) {
1014 &pSReply(" $type => $_");
1019 &pSReply(" $_ => $users{$user}{$_}");
1021 &pSReply("End of USER whois.");
1026 if ($message =~ /^bans(\s+(.*))?$/) {
1030 if ($arg ne "_default" and !&validChan($arg) ) {
1031 &pSReply("error: chan $chan is invalid.");
1036 if (!scalar keys %bans) {
1037 &pSReply("Ban list is empty.");
1042 &pSReply(" mask: expire, time-added, count, who-by, reason");
1043 foreach $c (keys %bans) {
1044 next unless (!defined $arg or $arg =~ /^\Q$c\E$/i);
1047 foreach (keys %{ $bans{$c} }) {
1048 my $val = $bans{$c}{$_};
1050 if (ref $val eq "ARRAY") {
1051 my @array = @{ $val };
1052 &pSReply(" $_: @array");
1054 &DEBUG("unknown ban: $val");
1058 &pSReply("END of bans.");
1063 if ($message =~ /^banlist(\s+(.*))?$/) {
1066 if (defined $arg and $arg !~ /^$mask_chan$/) {
1067 &pSReply("error: chan $chan is invalid.");
1071 &DEBUG("bans for global or arg => $arg.");
1072 foreach (keys %bans) { #CHANGE!!!
1073 &DEBUG(" $_ => $bans{$_}.");
1076 &DEBUG("End of bans.");
1077 &pSReply("END of bans.");
1082 if ($message =~ /^save$/) {
1083 return unless (&hasFlag("o"));
1092 $message =~ s/^addignore/+ignore/;
1093 $message =~ s/^(del|un)ignore/-ignore/;
1096 if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) {
1097 return unless (&hasFlag("o"));
1098 my $state = ($1 eq "+") ? 1 : 0;
1099 my $str = $1."ignore";
1107 my($mask,$chan,$time,$comment);
1110 if ($args =~ s/^($mask{nuh})\s*//) {
1113 &ERROR("no NUH mask?");
1117 if (!$state) { # delignore.
1118 if ( &ignoreDel($mask) ) {
1119 &pSReply("ok, deleted X ignores.");
1121 &pSReply("could not find $mask in ignore list.");
1131 if ($args =~ s/^($mask{chan}|\*)\s*//) {
1138 if ($args =~ s/^(\d+)\s*//) {
1148 $comment = "added by $who";
1151 if ( &ignoreAdd($mask, $chan, $time, $comment) > 1) {
1152 &pSReply("warn: $mask already in ignore list; written over anyway. FIXME");
1154 &pSReply("added $mask to ignore list.");
1160 if ($message =~ /^ignore(\s+(.*))?$/) {
1164 if ($arg !~ /^$mask{chan}$/) {
1165 &pSReply("error: chan $chan is invalid.");
1169 if (!&validChan($arg)) {
1170 &pSReply("error: chan $arg is invalid.");
1174 &pSReply("Showing bans for $arg only.");
1177 if (!scalar keys %ignore) {
1178 &pSReply("Ignore list is empty.");
1182 ### TODO: proper (eggdrop-like) formatting.
1184 &pSReply(" mask: expire, time-added, who, comment");
1185 foreach $c (keys %ignore) {
1186 next unless (!defined $arg or $arg =~ /^\Q$c\E$/i);
1189 foreach (keys %{ $ignore{$c} }) {
1190 my $ref = ref $ignore{$c}{$_};
1191 if ($ref eq "ARRAY") {
1192 my @array = @{ $ignore{$c}{$_} };
1193 &pSReply(" $_: @array");
1195 &DEBUG("unknown ignore line?");
1199 &pSReply("END of ignore.");
1205 if ($message =~ /^(\+|\-|add|del)user(\s+(.*))?$/i) {
1207 my $strstr = $1."user";
1208 my @args = split /\s+/, $3 || '';
1210 my $state = ($str =~ /^(\+|add)$/) ? 1 : 0;
1212 if (!scalar @args) {
1218 if (scalar @args != 2) {
1219 &pSReply(".+host requires hostmask argument.");
1222 } elsif (scalar @args != 1) {
1223 &pSReply("too many arguments.");
1227 if ($state) { # adduser.
1228 if (scalar @args == 1) {
1229 $args[1] = &getHostMask($args[0]);
1230 if (!defined $args[1]) {
1231 &ERROR("could not get hostmask?");
1236 if ( &userAdd(@args) ) { # success.
1237 &pSReply("Added $args[0]...");
1240 &pSReply("User $args[0] already exists");
1245 if ( &userDel($args[0]) ) { # success.
1246 &pSReply("Deleted $args[0] successfully.");
1249 &pSReply("User $args[0] does not exist.");
1256 if ($message =~ /^sched$/) {
1261 foreach (keys %sched) {
1262 next unless (exists $sched{$_}{TIME});
1263 $time{ $sched{$_}{TIME}-time() }{$_} = 1;
1266 next unless (exists $sched{$_}{RUNNING});
1271 foreach (sort { $a <=> $b } keys %time) {
1272 my $str = join(", ", sort keys %{ $time{$_} });
1273 &DEBUG("time => $_, str => $str");
1274 push(@time, "$str (".&Time2String($_).")");
1277 &pSReply( &formListReply(0, "Schedulers: ", @time ) );
1278 &pSReply( &formListReply(0, "Scheds to run: ", sort @list ) );
1279 &pSReply( &formListReply(0, "Scheds running(should not happen?) ", sort @run ) );