blob: 83504b4a4306eb756a458a63f06e987e3d781a27 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/*
2 * MGtool-1.0
3 * File: toolcmds.c
4 * Maintainer: Kirk@MorgenGrauen
5 */
6
7/*------------------------------------------*/
8/* the original Xtool is copyrighted by Hyp */
9/*------------------------------------------*/
10
11#include "tool.h"
12
13/*----------------------------------------------------------------------
14 * command functions
15 */
16
17int Xcall(string str)
18{
19 object obj, callobj;
20 string file, callstr, callfun, callexpr, error, errlog;
21 int *ru1, *ru2, xtime;
22 mixed res;
23
24 SECURE2(TRUE);
25 USAGE2(str, "xcall <object>-><function>(<arguments>)");
26 TK("Xcall: str: "+(str?str:"(NULL)"));
27 if(sscanf(str, "%s->%s(%s", callstr, callfun, callexpr)!=3)
28 return FALSE;
29 if(!(callobj=XFindObj(callstr)))
30 return TRUE;
31 else
32 {
33#if 0
34 write_file(TOOL_LOG,
35 sprintf("%s (%s) xcall %s (env: %s)\n",ctime(time()),
36 getuid(cloner),str,object_name(environment(cloner))));
37#endif
38 file=LPC_FILE+".c";
39 if(file_size(file)>0)
40 rm(file);
41 if(obj=find_object(LPC_FILE))
42 Destruct(obj);
43 obj=0;
44 write_file(file,
45 "#include <properties.h>\n"+
46 "#include <thing/properties.h>\n"+
47 "#include <defines.h>\n"+
48 "#include <wizlist.h>\n"+
49 "#include <moving.h>\n"+
50 "#include \"/secure/wizlevels.h\"\n"+
51 (file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
52 "mixed get(string str){return previous_object()->XFindObj(str);}\n"+
53 "mixed eval(object obj,mixed me,mixed here){return obj->"+callfun+"("+callexpr+";}\n");
54 errlog = ERR_FILE;
55 if(file_size(errlog)>0)
56 rm(errlog);
57 if(error=catch((LPC_FILE)->__nixgibts__()))
58 W("Error: "+error[1..]);
59 else
60 {
61 obj=find_object(LPC_FILE);
62 ru1=rusage();
63 error=catch(res=(mixed)obj->eval(callobj, cloner, ENV(cloner)));
64 ru2=rusage();
65 if(error)
66 W("Error: "+error[1..]);
67 else
68 {
69 xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
70 WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
71 PIPE_DELETE(pipe_of);
72 if(pipe_out&&pipe_of)
73 write_file(pipe_of,mixed_to_string(res, MAX_RECURSION)+"\n");
74 else
75 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
76 if(objectp(res))
77 m_add(variable, "result", res);
78 }
79 }
80 rm(file);
81 }
82 if(obj) Destruct(obj);
83 return TRUE;
84}
85
86int Xcallouts(string str)
87{
88 object obj;
89 mixed callouts, args;
90 string fun, tmp, file;
91 int delay, i, s;
92
93 SECURE2(TRUE);
94 TK("Xcallouts: str: "+(str?str:"(NULL)"));
95 if(!pipe_out)
96 {
97 USAGE1(str, "xcallo(uts) [search pattern]");
98 file=TMP_FILE;
99 if(file_size(file)>0)
100 rm(file);
101 if(!str)
102 str="^\\[~/";
103 else if(!regexp(({"dummy"}), str))
104 {
105 WDLN("Bad regular expression");
106 return TRUE;
107 }
108 }
109 else
110 {
111 USAGE1(str, "xcallo(uts)");
112 if(str&&str!="")
113 {
114 WDLN("More arguments than expected");
115 return TRUE;
116 }
117 }
118 callouts=call_out_info();
119 s=sizeof(callouts);
120 PIPE_DELETE(pipe_of);
121 for(i=0; i<s; i++)
122 {
123 if(callouts[i]&&pointerp(callouts[i]))
124 {
125 tmp=sprintf("%O %Os %O (%s)",callouts[i][0],callouts[i][2],
126 callouts[i][1],(sizeof(callouts[i])>3?
127 mixed_to_string(callouts[i][3],
128 MAX_RECURSION):"0"));
129 if(pipe_out&&pipe_of)
130 write_file(pipe_of,tmp+"\n");
131 else
132 if(sizeof(regexp(({tmp}), str)))
133 WLN(tmp);
134 }
135 }
136 return TRUE;
137}
138
139int Xcat(string str)
140{
141 string *tmp,file;
142 int s;
143
144 SECURE2(TRUE);
145 TK("Xcat: str: "+str);
146 if(!pipe_in)
147 {
148 USAGE2(str, "xcat <file>");
149 if(!(file=XFindFile(str)))
150 {
151 WDLN("Can't find file");
152 return TRUE;
153 }
154 }
155 else
156 {
157 if(str&&str!="-")
158 USAGE3("xcat -");
159
160 if (file_size(file=pipe_if)<0)
161 {
162 WDLN("Missing input to xcat");
163 return TRUE;
164 }
165 }
166 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
167 if(pipe_in&&pipe_if==PIPE_FILE)
168 rm(PIPE_FILE);
169 if (pipe_out&&pipe_of)
170 write_file(pipe_of,implode(tmp,"\n")+"\n");
171 else
172 WLN(implode(tmp,"\n"));
173 return TRUE;
174}
175
176int Xcd(string str)
177{
178 object dest;
179 string path;
180
181 SECURE2(TRUE);
182 USAGE1(str, "xcd [object]");
183 TK("Xcd: str: "+(str?str:"(NULL)"));
184 if(!str)
185 {
186 if(!(path=(string)cloner->QueryProp("start_home")))
187 path="/";
188 }
189 else if((dest=XFindObj(str,1)))
190 path="/"+implode(old_explode(object_name(dest),"/")[0..<2],"/");
191 else
192 path="";
193
194 TK("Xcd: path: "+(path?path:"(NULL)"));
195 if(!sizeof(path))
196 path=str;
197 PL->_cd(path);
198
199 return TRUE;
200}
201
202int Xclean(string str)
203{
204 object env;
205
206 SECURE2(TRUE);
207 USAGE1(str, "xcle(an) [object]");
208 TK("Xclean: str: "+(str?str:"(NULL)"));
209 if(!str)
210 env=ENV(cloner);
211 if(env||(env=XFindObj(str)))
212 {
213 PrintShort("Cleaning: ", env);
214 filter(filter(all_inventory(env), #'is_not_player),//'
215 "Destruct", ME);
216 }
217 return TRUE;
218}
219
220int Xclone(string str)
221{
222 object obj;
223 string file, errlog, error;
224
225 SECURE2(TRUE);
226 USAGE2(str, "xclo(ne) <filename>");
227 if(!(file=XFindFile(str))) return TRUE;
228 errlog=ERR_FILE;
229 if(file_size(errlog)>0) rm(errlog);
230 WLN("Clone: "+short_path(file));
231 if(!(error=catch(obj=clone_object(file))))
232 {
233 m_add(variable, "clone", obj);
234 if(!MoveObj(obj, ENV(cloner), TRUE))
235 WDLN("Cannot move object into this room");
236 else if(!obj->QueryNoGet())
237 {
238 if(!MoveObj(obj, cloner, TRUE))
239 WDLN("Cannot move object into your inventory");
240 }
241 }
242 else
243 W("Error: "+error[1..]);
244 return TRUE;
245}
246
247int Xuclone(string str)
248{
249 object obj;
250 string file, errlog, error;
251
252 SECURE2(TRUE);
253 USAGE2(str, "xuclo(ne) <filename>");
254 if(!(file=XFindFile(str))) return TRUE;
255 errlog=ERR_FILE;
256 if(file_size(errlog)>0) rm(errlog);
257 if(obj=find_object(file)) {
258 Destruct(obj);
259 WLN("Update and clone: "+short_path(file));
260 }
261 else
262 WLN("Clone: "+short_path(file));
263 if(!(error=catch(obj=clone_object(file))))
264 {
265 variable["clone"] = obj;
266 if(!MoveObj(obj, ENV(cloner), TRUE))
267 WDLN("Cannot move object into this room");
268 else if(!obj->QueryNoGet())
269 {
270 if(!MoveObj(obj, cloner, TRUE))
271 WDLN("Cannot move object into your inventory");
272 }
273 }
274 else
275 W("Error: "+error[1..]);
276 return TRUE;
277}
278
279int Xcmds(string str)
280{
281 object obj;
282 mixed *cmds;
283 int i, s;
284
285 SECURE2(TRUE);
286 USAGE1(str, "xcm(ds) [object]");
287 TK("Xcmds: str: "+(str?str:"(NULL)"));
288 if(!str)
289 obj=ENV(cloner);
290 else if(!(obj=XFindObj(str)))
291 {
292 WDLN("Can't find object");
293 return TRUE;
294 }
295 s=sizeof(cmds=query_actions(cloner,1|2|4|8|16));
296 PIPE_DELETE(pipe_of);
297 for(i=0; i<s; i+=5)
298 if(cmds[i+3]==obj)
299 if(pipe_out&&pipe_of)
300 write_file(pipe_of,ALEFT(cmds[i]+" ", 15, ".")+
301 (cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()\n");
302 else
303 WLN(ALEFT(cmds[i]+" ", 15, ".")+
304 (cmds[i+2] ? " * " : " . ")+cmds[i+4]+"()");
305 return TRUE;
306}
307
308int Xdbg(string str)
309{
310 object obj;
311
312 SECURE2(TRUE);
313 USAGE2(str, "xdb(g) <object>");
314 TK("Xdbg: str: "+(str?str:"(NULL)"));
315 if((obj=XFindObj(str)))
316 {
317 debug_info(1, obj);
318 debug_info(0, obj);
319 }
320 return TRUE;
321}
322
323int Xdclean(string str)
324{
325 object env;
326
327 SECURE2(TRUE);
328 USAGE1(str, "xdc(lean) [object]");
329 TK("Xdclean: str: "+(str?str:"(NULL)"));
330 if(!str)
331 env=ENV(cloner);
332 if(env||(env=XFindObj(str)))
333 {
334 PrintShort("Deep cleaning: ", env);
335 filter(filter(all_inventory(env), #'is_not_player, ME),//'
336 "DeepClean", ME);
337 }
338 return TRUE;
339}
340
341int Xddes(string str)
342{
343 object obj;
344
345 SECURE2(TRUE);
346 USAGE2(str, "xdd(es) <object>");
347 TK("Xddes: str: "+(str?str:"(NULL)"));
348 if((obj=XFindObj(str)))
349 {
350 PrintShort("Deep destruct: ", obj);
351 filter(deep_inventory(obj), "Destruct", ME);
352 Destruct(obj);
353 }
354 return TRUE;
355}
356
357int Xdes(string str)
358{
359 object obj;
360
361 SECURE2(TRUE);
362 USAGE2(str, "xde(s) <object>");
363 TK("Xdes: str: "+(str?str:"(NULL)"));
364 if((obj=XFindObj(str)))
365 {
366 PrintShort("Destruct: ",obj);
367 Destruct(obj);
368 }
369 return TRUE;
370}
371
372int Xdlook(string str)
373{
374 object obj;
375
376 SECURE2(TRUE);
377 USAGE1(str, "xdl(ook) [object]");
378 TK("Xdlook: str: "+(str?str:"(NULL)"));
379 if(!str)
380 obj=cloner;
381 if(obj||(obj=XFindObj(str)))
382 {
383 PIPE_DELETE(pipe_of);
384 DeepPrintShort(obj,NULL,NULL,(pipe_out&&pipe_of)?pipe_of:"");
385 }
386 return TRUE;
387}
388
389int Xdo(string str)
390{
391 int i, n, s;
392 string *strs, cmd;
393
394 SECURE2(TRUE);
395 USAGE2(str, "xdo [<number1>#]<command1>[;[<number2>#]<command2>] ...");
396 if(!str||str==""||!(s=sizeof(strs=strip_explode(str, ";"))))
397 return FALSE;
398 for(i=0; i<s; i++)
399 {
400 if(strs[i])
401 {
402 switch(sscanf(strs[i], "%d#%s", n, cmd))
403 {
404 case 0:
405 if(!Command(strs[i])) return TRUE;
406 break;
407 case 1:
408 if(cmd&&(!Command(cmd))) return TRUE;
409 break;
410 case 2:
411 n= n<1 ? 1 : n;
412 if(cmd)
413 {
414 while(n--)
415 if(!Command(cmd)) return TRUE;
416 }
417 break;
418 }
419 }
420 }
421 return TRUE;
422}
423
424int Xdupdate(string str)
425{
426 int i, s;
427 object obj;
428 string file, *list;
429
430 SECURE2(TRUE);
431 USAGE2(str, "xdu(pdate) <filename>");
432 if(!(file=XFindFile(str)))
433 return TRUE;
434 if(file[<2..<1]==".c")
435 file=file[0..<3];
436 if(obj=XFindObj(file))
437 {
438 PrintShort("Deep updating: ", obj);
439 list=inherit_list(obj);
440 for(s=sizeof(list); i<s; i++)
441 {
442 if(obj=find_object(list[i]))
443 Destruct(obj);
444 }
445 }
446 return TRUE;
447}
448
449int Xecho(string str)
450{
451 TK("Xecho: str: "+(str?str:"(NULL)"));
452 WLN(str);
453 return TRUE;
454}
455
456int Xeval(string str)
457{
458 object obj;
459 string file, error;
460 int *ru1, *ru2, xtime;
461 mixed res;
462
463 SECURE2(TRUE);
464 USAGE2(str, "xev(al) <expression>");
465 file=LPC_FILE+".c";
466 if(file_size(file)>0)
467 rm(file);
468 if(obj=find_object(LPC_FILE))
469 Destruct(obj);
470#if 0
471 write_file(TOOL_LOG,
472 sprintf("%s (%s) xeval %s\n",
473 ctime(time()),getuid(cloner),str));
474#endif
475 write_file(file,
476 "#include <properties.h>\n"+
477 "#include <thing/properties.h>\n"+
478 "#include <defines.h>\n"+
479 "#include <wizlist.h>\n"+
480 "#include <moving.h>\n"+
481 "#include \"/secure/wizlevels.h\"\n"+
482 (file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
483 "get(str){return previous_object()->XFindObj(str);}\n"+
484 "eval(me,here){return "+str+";}");
485 if(error=catch(obj=clone_object(file)))
486 W("Error: "+error[1..]);
487 else
488 {
489 ru1=rusage();
490 error=catch(res=(mixed)obj->eval(cloner, ENV(cloner)));
491 ru2=rusage();
492 if(error)
493 W("Error: "+error[1..]);
494 else
495 {
496 xtime=ru2[0]-ru1[0]+ru2[1]-ru1[1];
497 WDLN("Evaluation time: "+(xtime<0 ? 0 : xtime)+" ms");
498 PIPE_DELETE(pipe_of);
499 if(pipe_out&&pipe_of)
500 write_file(pipe_of,mixed_to_string(res,MAX_RECURSION)+"\n");
501 else
502 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
503 if(objectp(res))
504 variable["result"] = res;
505 }
506 }
507 rm(file);
508 if(obj)
509 Destruct(obj);
510 return TRUE;
511}
512
513int Xforall(string str)
514{
515 int i, s, t, u;
516 string pat, cmd, arg, *strs, *files, fh, fr, fe, ft, ff;
517
518 SECURE2(TRUE);
519 USAGE2(str, "xfo(rall) <filepattern> <command>");
520 if(sscanf(str, "%s %s", pat, arg)!=2)
521 return FALSE;
522 files=long_get_dir(pat, FALSE);
523 if(!(s=sizeof(files)))
524 {
525 WDLN("No matching files found");
526 return TRUE;
527 }
528 strs=old_explode(files[0], "/");
529 fh="/";
530 if(t=sizeof(strs)-1)
531 fh+=implode(strs[0..t-1], "/");
532 for(i=0; i<s; i++)
533 {
534 ft=old_explode(files[i], "/")[t];
535 if((u=sizeof(strs=old_explode(ft, ".")))&&--u)
536 {
537 ff=implode(strs[0..u-1], ".");
538 fr=fh+"/"+ff;
539 fe=strs[u];
540 }
541 else
542 {
543 fe="";
544 ff=ft;
545 fr=files[i];
546 }
547 cmd=string_replace(arg, "!!", files[i]);
548 cmd=string_replace(cmd, "!e", fe);
549 cmd=string_replace(cmd, "!f", ff);
550 cmd=string_replace(cmd, "!h", fh);
551 cmd=string_replace(cmd, "!r", fr);
552 cmd=string_replace(cmd, "!t", ft);
553 if(!(Command(cmd)))
554 break;
555 }
556 return TRUE;
557}
558
559int Xgoto(string str)
560{
561 object obj, tmp;
562
563 SECURE2(TRUE);
564 USAGE1(str, "xgo(to) [object]");
565 if(!str) str="~/workroom";
566 if(!(obj=XFindObj(str)))
567 {
568 if(!(str=XFindFile(str)))
569 return TRUE;
570 if(catch(call_other(str, "???")))
571 return TRUE;
572 obj=find_object(str);
573 }
574 tmp=obj;
575 while(obj&&living(obj))
576 obj=ENV(obj);
577 cloner->move(obj ? obj : tmp, M_TPORT);
578 return TRUE;
579}
580
581int Xgrep(string str)
582{
583 int i, s, t, mode;
584 string *files, *ts;
585
586 SECURE2(TRUE);
587 TK("Xgrep: str: "+(str?str:"(NULL)"));
588 mode=0;
589 if(!pipe_in)
590 {
591 USAGE2(str, "xgr(ep) [-i] [-v] <regexp> <filepattern>");
592 if(!(ts=old_explode(str, " "))||!(s=sizeof(ts)))
593 return FALSE;
594 while(ts[0][0]=='-')
595 {
596 if(s<3)
597 {
598 WDLN("Too few arguments to xgrep");
599 return FALSE;
600 }
601 switch(ts[0])
602 {
603 case "-v":
604 mode|=XGREP_REVERT;
605 ts=ts[1..];
606 s--;
607 break;
608 case "-i":
609 mode|=XGREP_ICASE;
610 ts=ts[1..];
611 s--;
612 break;
613 case "-vi":
614 case "-iv":
615 mode|=XGREP_REVERT;
616 mode|=XGREP_ICASE;
617 ts=ts[1..];
618 s--;
619 break;
620 default:
621 WDLN("Unknown option "+ts[0]+" given to xgrep");
622 return FALSE;
623 }
624 }
625 str=implode(ts[0..s-2], " ");
626 }
627 else
628 {
629 if(!((ts=old_explode(str, " "))&&(s=sizeof(ts))))
630 USAGE3("xgr(ep) [-i] [-v] <regexp>");
631 while(ts[0][0]=='-')
632 {
633 if(s<2)
634 {
635 WDLN("Too few arguments to xgrep");
636 return FALSE;
637 }
638 switch(ts[0])
639 {
640 case "-v":
641 mode|=XGREP_REVERT;
642 ts=ts[1..];
643 s--;
644 break;
645 case "-i":
646 mode|=XGREP_ICASE;
647 ts=ts[1..];
648 s--;
649 break;
650 case "-iv":
651 case "-vi":
652 mode|=XGREP_REVERT;
653 mode|=XGREP_ICASE;
654 ts=ts[1..];
655 s--;
656 break;
657 default:
658 WDLN("Unknown option "+ts[0]+" given to xgrep");
659 return FALSE;
660 }
661 }
662 str=implode(ts[0..s-1], " ");
663 }
664
665 if(mode&XGREP_ICASE)
666 str=lower_case(str);
667 if(!(regexp(({"dummy"}), str)))
668 {
669 WDLN("Bad regular expression");
670 return TRUE;
671 }
672 if(!pipe_in)
673 {
674 if(file_size(TMP_FILE)>0)
675 rm(TMP_FILE);
676 if((t=sizeof(files=long_get_dir(XFile(ts[s-1]), FALSE)))&&
677 (file_size(files[0])>=0))
678 {
679 for(i=0; i<t; i++)
680 XGrepFile(str, files[i], mode);
681 if(pipe_out&&pipe_of)
682 {
683 PIPE_DELETE(pipe_of);
684 if(!pipe_ovr)
685 {
686 write_file(pipe_of,read_file(TMP_FILE,0,PIPE_MAX));
687 rm(TMP_FILE);
688 }
689 else
690 rename(TMP_FILE,pipe_of);
691 }
692 else
693 {
694 W(read_file(TMP_FILE,0,PIPE_MAX));
695 rm(TMP_FILE);
696 }
697 }
698 else
699 WDLN("Cannot read file(s)");
700 }
701 else
702 {
703 string *tmp;
704 if(file_size(pipe_if)<0)
705 {
706 WDLN("Missing input to xgrep");
707 return TRUE;
708 }
709 TK("Xgrep: str: "+str+" mode: "+mode);
710 s=sizeof(tmp=old_explode(read_file(pipe_if,0,PIPE_MAX),"\n"));
711 PIPE_DELETE(pipe_of);
712 for(i=0;i<s;i++)
713 {
714 // TK(tmp[i]+"<->"+str);
715 if(sizeof(regexp(({(mode&XGREP_ICASE?lower_case(tmp[i]):tmp[i])}),str)))
716 {
717 // TK("Xgrep: matched!");
718 if(!(mode&XGREP_REVERT))
719 if(pipe_out&&pipe_of)
720 write_file(pipe_of,tmp[i]+"\n");
721 else
722 WLN(tmp[i]);
723 }
724 else
725 if(mode&XGREP_REVERT)
726 if(pipe_out&&pipe_of)
727 write_file(pipe_of,tmp[i]+"\n");
728 else
729 WLN(tmp[i]);
730 }
731 }
732 return TRUE;
733}
734
735int Xhbeats(string str)
736{
737 object obj;
738 object *hbeatinfo;
739 string tmp, file;
740 int i, s;
741
742 SECURE2(TRUE);
743 TK("Xhbeats: str: "+(str?str:"(NULL)"));
744 if(!pipe_out)
745 {
746 USAGE1(str, "xhb(eats) [search pattern]");
747 if(!str)
748 str=RNAME(cloner);
749 else if(!regexp(({"dummy"}), str))
750 {
751 WDLN("Bad regular expression");
752 return TRUE;
753 }
754 }
755 else
756 {
757 USAGE1(str,"xhb(eats)");
758 if(str&&str!="")
759 {
760 WDLN("More arguments than expected");
761 return TRUE;
762 }
763 }
764 s=sizeof(hbeatinfo=heart_beat_info());
765 PIPE_DELETE(pipe_of);
766 for(i=0; i<s; i++)
767 if(hbeatinfo[i]&&objectp(hbeatinfo[i]))
768 {
769 tmp=ObjFile(hbeatinfo[i]);
770 if(sizeof(regexp(({tmp}), str)))
771 if(pipe_out&&pipe_of)
772 write_file(pipe_of, tmp+"\n");
773 else
774 WLN(tmp);
775 }
776 return TRUE;
777}
778
779int Xhead(string str)
780{
781 int lines;
782 string *tmp, file;
783
784 SECURE2(TRUE);
785 TK("Xhead: str: "+(str?str:"(NULL)"));
786 if(!pipe_in)
787 {
788 USAGE2(str, "xhead <-#> <file>");
789 if(sscanf(str,"-%d %s",lines,file)!=2)
790 return FALSE;
791 if(!(file=XFindFile(file)))
792 return FALSE;
793 }
794 else
795 {
796 USAGE2(str, "xhead <-#>");
797 if(sscanf(str,"-%d",lines)!=1)
798 return FALSE;
799 if (file_size(file=pipe_if)<0)
800 {
801 WDLN("Missing input to xhead");
802 return TRUE;
803 }
804 }
805 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[0..lines-1];
806 if(pipe_in&&pipe_if==PIPE_FILE)
807 rm(PIPE_FILE);
808 if (pipe_out&&pipe_of)
809 {
810 PIPE_DELETE(pipe_of);
811 write_file(pipe_of,implode(tmp,"\n")+"\n");
812 }
813 else
814 WDLN(implode(tmp,"\n"));
815 return TRUE;
816}
817
818int Xhelp(string str)
819{
820 SECURE2(TRUE);
821 USAGE1(str, "xhe(lp)");
822 XMoreFile(TOOL_MANPAGE, FALSE);
823 return TRUE;
824}
825
826int Xids(string str)
827{
828 object obj;
829
830 SECURE2(TRUE);
831 USAGE2(str, "xid(s) <object>");
832 TK("Xids: str: "+(str?str:"(NULL)"));
833 if((obj=XFindObj(str)))
834 WLN("UID=\""+getuid(obj)+"\" / EUID=\""+geteuid(obj)+"\"");
835 return TRUE;
836}
837
838int Xinfo(string str)
839{
840 object obj;
841
842 SECURE2(TRUE);
843 USAGE2(str, "xinf(o) <object>");
844 TK("Xinfo: str: "+(str?str:"(NULL)"));
845 if((obj=XFindObj(str)))
846 {
847 if(is_player(obj))
848 {
849 WLN(PlayerWho(obj));
850 WLN(PlayerMail(obj, FALSE));
851 WLN(PlayerIP(obj, FALSE));
852 WLN(PlayerRace(obj, FALSE));
853 WLN(PlayerDomain(obj, FALSE));
854 WLN(PlayerStats(obj, FALSE));
855 WLN(PlayerSnoop(obj, FALSE));
856 }
857 else
858 WDLN("Sorry, this is not a player");
859 }
860 return TRUE;
861}
862
863int Xinherit(string str)
864{
865 int s;
866 object obj;
867 string *strs, *inlist;
868
869 SECURE2(TRUE);
870 USAGE2(str, "xinh(erit) <object> [function]");
871 TK("Xinherit: str: "+str);
872 if(!(strs=strip_explode(str, " ")))
873 return FALSE;
874 if(obj=XFindObj(strs[0]))
875 {
876 inlist=inherit_list(obj);
877 s=sizeof(inlist);
878 while(s--)
879 {
880 if(catch(call_other(inlist[s], "???")))
881 {
882 WDLN("Failed to load all inheritance objects");
883 return TRUE;
884 }
885 }
886 obj=find_object(inlist[0]);
887 PIPE_DELETE(pipe_of);
888 if(sizeof(strs)==1)
889 Inheritance(obj ,0 ,"");
890 else
891 Inheritance(obj, strs[1], "");
892 }
893 return TRUE;
894}
895
896int Xinventory(string str)
897{
898 int i, short;
899 object item;
900 mixed who;
901
902 SECURE2(TRUE);
903 USAGE1(str, "xi [-s] [player]");
904 TK("Xinventory: str: "+str);
905 short=0;
906 who=cloner;
907 if(str&&str!="")
908 {
909 if(str=="-s")
910 {
911 short=1;
912 who=cloner;
913 }
914 else if(sscanf(str,"-s %s",who))
915 {
916 short=1;
917 who=XFindObj(who);
918 }
919 else if(sscanf(str,"%s",who))
920 {
921 short=0;
922 who=XFindObj(who);
923 }
924 else
925 who=cloner;
926 }
927 if(!who)
928 return FALSE;
929 PIPE_DELETE(pipe_of);
930 if(!(pipe_out&&pipe_of))
931 WLN(who->name(WESSEN)+" Inventory:"+(short?" (short)":""));
932 if(!short)
933 if(pipe_out&&pipe_of)
934 FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item, pipe_of);
935 else
936 FORALL(item, who) PrintShort(ARIGHT(++i+". ", 4, " "), item);
937 else
938 if(pipe_out&&pipe_of)
939 FORALL(item, who) write_file(pipe_of,++i+". ["+object_name(item)+"]\n");
940 else
941 FORALL(item, who) WLN(++i+". ["+object_name(item)+"]");
942 return TRUE;
943}
944
945int Xlag(string str)
946{
947 int i;
948 float *lag;
949 object daemon;
950 string lags;
951
952 if(file_size(LAG_O_DAEMON+".c")<=0)
953 {
954 WLN("Sorry, lag-o-daemon is missing!");
955 return TRUE;
956 }
957
958 LAG_O_DAEMON->MachHin();
959 if(!(daemon=find_object(LAG_O_DAEMON)))
960 lag=({-1.0,-1.0,-1.0});
961 else
962 lag=(float *)daemon->read_lag_data();
963 lags="Letzte 60 min: ";
964 if(lag[0]>=0.0)
965 {
966 for(i=round(lag[0])-1;i>=0;i--)
967 lags+="#";
968 lags+=" ("+sprintf("%.1f",lag[0])+"%)";
969 }
970 else
971 lags+="N/A";
972 lags+="\nLetzte 15 min: ";
973 if(lag[1]>=0.0)
974 {
975 for(i=round(lag[1])-1;i>=0;i--)
976 lags+="#";
977 lags+=" ("+sprintf("%.1f",lag[1])+"%)";
978 }
979 else
980 lags+="N/A";
981 lags+="\nLetzte Minute: ";
982 if(lag[2]>=0.0)
983 {
984 for(i=round(lag[2])-1;i>=0;i--)
985 lags+="#";
986 lags+=" ("+sprintf("%.1f",lag[2])+"%)";
987 }
988 else
989 lags+="N/A";
990 WLN(lags);
991 return TRUE;
992}
993
994int Xlight(string str)
995{
996 int s, addlight;
997
998 SECURE2(TRUE);
999 USAGE1(str, "xli(ght) [light]");
1000 if(str)
1001 {
1002 if(!sscanf(str, "%d", addlight))
1003 return FALSE;
1004 xlight+=addlight;
1005 cloner->AddIntLight(addlight);
1006 }
1007 WDLN("Current light levels: "+TOOL_NAME+"="+xlight+", room="+
1008 ENV(cloner)->QueryIntLight());
1009 return TRUE;
1010}
1011
1012int Xload(string str)
1013{
1014 int i, f;
1015 object obj, *inv, vroom;
1016 string file, errlog, error, *strs;
1017
1018 SECURE2(TRUE);
1019 USAGE2(str, "xloa(d) <filename>");
1020 if(!(file=XFindFile(str)))
1021 return TRUE;
1022 errlog=ERR_FILE;
1023 if(file_size(errlog)>0)
1024 rm(errlog);
1025 if(obj=find_object(file))
1026 {
1027 if(catch(call_other(VOID, "???")))
1028 {
1029 WDLN("Error: cannot find "+VOID+" to rescue players");
1030 return TRUE;
1031 }
1032 else
1033 vroom = find_object(VOID);
1034 if(inv=filter(all_inventory(obj), #'is_player, ME))//'
1035 for(i=0; i<sizeof(inv); i++)
1036 MoveObj(inv[i], vroom, TRUE);
1037 Destruct(obj);
1038 WLN("Update and load: "+file);
1039 }
1040 else
1041 WLN("Load: "+file);
1042 if(error=catch(call_other(file, "???")))
1043 {
1044 W("Error: "+error[1..]);
1045 if(vroom)
1046 tell_object(vroom, "*** Failed to load room. You are in the void!\n");
1047 }
1048 else if(inv)
1049 {
1050 obj=find_object(file);
1051 for(i=0; i<sizeof(inv); i++)
1052 if(inv[i])
1053 MoveObj(inv[i], obj, TRUE);
1054 }
1055 return TRUE;
1056}
1057
1058int Xlook(string str)
1059{
1060 object obj;
1061 string st;
1062 string file;
1063
1064 SECURE2(TRUE);
1065 USAGE1(str, "xloo(k) [object]");
1066 TK("Xlook: str: "+str);
1067 PIPE_DELETE(pipe_of);
1068 file = pipe_out&&pipe_of ? pipe_of : "";
1069 if(str&&str!="")
1070 {
1071 if((obj=XFindObj(str)))
1072 PrintObj(obj,file);
1073 }
1074 else
1075 {
1076 obj=ENV(cloner);
1077 PrintObj(obj,file);
1078 }
1079 return TRUE;
1080}
1081
1082int Xlpc(string str)
1083{
1084 object obj;
1085 string file, error;
1086 int *ru1, *ru2, time;
1087 mixed res;
1088
1089 SECURE2(TRUE);
1090 USAGE2(str, "xlp(c) <lpc code>");
1091 file=LPC_FILE+".c";
1092 if(file_size(file)>0)
1093 rm(file);
1094 if(obj=find_object(LPC_FILE))
1095 Destruct(obj);
1096 write_file(file,
1097 "#pragma no_warn_missing_return,strong_types,warn_deprecated,rtt_checks\n"
1098 "#include <properties.h>\n"
1099 "#include <thing/properties.h>\n"
1100 "#include <defines.h>\n"
1101 "#include <wizlist.h>\n"
1102 "#include <moving.h>\n"
1103 "#include \"/secure/wizlevels.h\"\n"
1104 +(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
1105 "object get(string str){return previous_object()->XFindObj(str);}\n"+
1106 "mixed eval(mixed me, mixed here){"+str+"}");
1107 if(error=catch(obj=clone_object(file)))
1108 W("Error: "+error[1..0]);
1109 else
1110 {
1111 ru1=rusage();
1112 error=catch(res=(mixed)obj->eval(cloner, ENV(cloner)));
1113 ru2=rusage();
1114 if(error)
1115 W("Error: "+error[1..]);
1116 else
1117 {
1118 time=ru2[0]-ru1[0]+ru2[1]-ru1[1];
1119 WDLN("Evaluation time: "+(time<0 ? 0 : time)+" ms");
1120 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
1121 if(objectp(res))
1122 variable["result"] = res;
1123 }
1124 }
1125 rm(file);
1126 if(obj)
1127 Destruct(obj);
1128 return TRUE;
1129}
1130
1131int Xman(string str)
1132{
1133 string manpage;
1134 int i, found;
1135
1136 SECURE2(TRUE);
1137 USAGE2(str, "xma(n) <manpage>");
1138 W("Man: ");
1139 for(i=0, found=0; i<sizeof(manpath); i++)
1140 {
1141 manpage=manpath[i]+str;
1142 if(file_size(manpage)>=0)
1143 {
1144 WLN(manpage);
1145 XMoreFile(manpage, FALSE);
1146 found=1;
1147 break;
1148 }
1149 }
1150 if(!found)
1151 WLN("- no help available -");
1152 return TRUE;
1153}
1154
1155int Xmore(string str)
1156{
1157 string *args, file;
1158 int line;
1159
1160 SECURE2(TRUE);
1161 TK("Xmore: str: "+str);
1162 if (!pipe_in)
1163 {
1164 USAGE2(str, "xmor(e) <filename> [start]");
1165 switch(sizeof(args=strip_explode(str, " ")))
1166 {
1167 case 1:
1168 moreoffset=1;
1169 break;
1170 case 2:
1171 sscanf(args[1], "%d", line);
1172 moreoffset= line>0 ? line : 1;
1173 break;
1174 default:
1175 return FALSE;
1176 }
1177 if(file=XFindFile(args[0]))
1178 XMoreFile(file, TRUE);
1179 }
1180 else
1181 {
1182 if(file_size(pipe_if)<0)
1183 {
1184 WDLN("Missing input to xmore");
1185 return TRUE;
1186 }
1187 if (!str||str=="")
1188 line=1;
1189 else if (sscanf(str, "%d", line)!=1)
1190 USAGE3("xmor(e) [start]");
1191 moreoffset= line>0 ? line : 1;
1192 XMoreFile(pipe_if, TRUE);
1193 }
1194 return TRUE;
1195}
1196
1197int Xmove(string str)
1198{
1199 object obj1, obj2;
1200 string what, into;
1201
1202 SECURE2(TRUE);
1203 USAGE2(str, "xmov(e) <object> into <object>");
1204 if((sscanf(str, "%s into %s", what, into)==2)&&
1205 (obj1=XFindObj(what))&&(obj2=XFindObj(into)))
1206 MoveObj(obj1, obj2, FALSE);
1207 return TRUE;
1208}
1209
1210int Xmsg(string str)
1211{
1212 string tmp;
1213
1214 SECURE2(TRUE);
1215 TK("Xmsg: str: "+str);
1216 USAGE1(str, "xms(g) [to <object>|all]");
1217 if(!str||str=="")
1218 {
1219 WDLN("Send message into room");
1220 say("Message from "+CRNAME(cloner)+":\n");
1221 if(pipe_in&&pipe_if)
1222 say(read_file(pipe_if,0,PIPE_MAX));
1223 else
1224 {
1225 WDLN("End message with \".\" or \"**\"");
1226 input_to("XMsgSay");
1227 }
1228 return TRUE;
1229 }
1230 else if(sscanf(str, "to %s", tmp))
1231 {
1232 if(msgto=XFindObj(tmp))
1233 {
1234 PrintShort("Send message to: ", msgto);
1235 tell_object(msgto, "Message from "+CRNAME(cloner)+" to you:\n");
1236 if(pipe_in&&pipe_if)
1237 tell_object(msgto,read_file(pipe_if,0,PIPE_MAX));
1238 else
1239 {
1240 WDLN("End message with \".\" or \"**\"");
1241 input_to("XMsgTell");
1242 }
1243 }
1244 return TRUE;
1245 }
1246 else if(str=="all")
1247 {
1248 WDLN("Send message to all players");
1249 shout("Message from "+CRNAME(cloner)+" to all:\n");
1250 if(pipe_in&&pipe_if)
1251 shout(read_file(pipe_if,0,PIPE_MAX));
1252 else
1253 {
1254 WDLN("End message with \".\" or \"**\"");
1255 input_to("XMsgShout");
1256 }
1257 return TRUE;
1258 }
1259 return FALSE;
1260}
1261
1262int Xmtp(string str)
1263{
1264 int s;
1265 string *strs, opt, dir, file;
1266
1267 SECURE2(TRUE);
1268 USAGE2(str, "xmt(p) [options] <directory> <filename>");
1269 s=sizeof(strs=old_explode(str, " "));
1270 if(s<2)
1271 return FALSE;
1272 else if(s==2)
1273 opt="";
1274 else
1275 opt=implode(strs[0..s-3], " ");
1276 if(!(dir="/"+(string)MASTER->valid_read(strs[s-2], geteuid(),
1277 "get_dir", ME))) {
1278 WDLN("No permission to open directory for reading");
1279 return TRUE;
1280 }
1281 if(!(file="/"+(string)MASTER->valid_write(strs[s-1], geteuid(),
1282 "write_file", ME))) {
1283 WDLN("No permission to open script file for writing");
1284 return TRUE;
1285 }
1286 if(file_size(dir)!=-2 || file_size(file)==-2)
1287 return FALSE;
1288 XmtpScript(dir, file, opt);
1289 WDLN("Done");
1290 return TRUE;
1291}
1292
1293int Xproc(string str)
1294{
1295 int s;
1296 string *strs;
1297
1298 SECURE2(TRUE);
1299 USAGE1(str, "xproc [-c] [-l] [-m] [-u] [-v]");
1300
1301 if(file_size(TOOL_PATH+"/proc")!=-2)
1302 {
1303 WLN("Sorry, no /proc information available!");
1304 return TRUE;
1305 }
1306
1307 if(!str||str==""||!(s=sizeof(strs=old_explode(str, " "))))
1308 {
1309 WLN("Load averages:");
1310 cat(TOOL_PATH+"/proc/loadavg");
1311 return TRUE;
1312 }
1313
1314 while(s=sizeof(strs))
1315 {
1316 switch(strs[0])
1317 {
1318 case "-c":
1319 WLN("CPU info:");
1320 cat(TOOL_PATH+"/proc/cpuinfo");
1321 break;
1322 case "-l":
1323 WLN("Load averages:");
1324 cat(TOOL_PATH+"/proc/loadavg");
1325 break;
1326 case "-m":
1327 WLN("Memory usage:");
1328 cat(TOOL_PATH+"/proc/meminfo");
1329 break;
1330 case "-u":
1331 WLN("Uptime:");
1332 cat(TOOL_PATH+"/proc/uptime");
1333 break;
1334 case "-v":
1335 WLN("Version:");
1336 cat(TOOL_PATH+"/proc/version");
1337 break;
1338 default:
1339 WLN("Unknown option: "+strs[0]);
1340 }
1341 strs=strs[1..];
1342 }
1343 return TRUE;
1344}
1345
1346int Xprof(string str)
1347{
1348 string *funcs, inh, tmp;
1349 mixed *data, *d;
1350 mapping xpr;
1351 object obj;
1352 int i, rn;
1353
1354 SECURE2(TRUE);
1355 USAGE2(str, "xprof <<-c>|<-C> <file>>|<object>");
1356 if(str[0..2]=="-c "||str[0..2]=="-C ")
1357 {
1358 rn=(str[1]=='C');
1359 if(str=XFindFile(str[3..]))
1360 {
1361 inh=str=str[0..<3];
1362 if(obj=find_object(inh))
1363 Destruct(obj);
1364 if(catch(call_other(inh,"???")))
1365 return TRUE;
1366 obj=find_object(inh);
1367 if(rn)
1368 {
1369 inh+=".xprof.c";
1370 rm(inh);
1371 str+=".c";
1372 rename(str, inh);
1373 }
1374 else
1375 {
1376 str=XPROF_FILE;
1377 rm(str);
1378 }
1379 tmp="inherit \""+inh+"\";\n#include \""+XPROF_MACRO+"\"\n";
1380 funcs=m_indices(mkmapping(functionlist(obj, 0x08000001)))-({"__INIT"});
1381 for(i=sizeof(funcs); i--;)
1382 tmp+="F("+funcs[i]+",\""+funcs[i]+"\","+
1383 "(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9))\n";
1384 write_file(str, tmp);
1385 WDLN("Done");
1386 }
1387 }
1388 else if(obj=XFindObj(str))
1389 {
1390 if(xpr=(mapping)obj->__query_xprof_data__())
1391 {
1392 funcs=m_indices(xpr);
1393 data=m_values(xpr);
1394 rm(TMP_FILE);
1395 str="Evaluation cost per function:\nNAME "+
1396 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1397 for(i=sizeof(funcs); i--;)
1398 {
1399 if(d=data[i]) {
1400 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1401 ARIGHT(" "+d[1],10,".") +" "+ARIGHT(" "+d[3],10,".")+" | "+
1402 ARIGHT(" "+d[1]/d[0],9,".") +" "+ARIGHT(" "+d[3]/d[0],9,".");
1403 }
1404 }
1405 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1406 write_file(TMP_FILE,str);
1407 str="\nElapsed time per function:\nNAME "+
1408 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1409 funcs=m_indices(xpr);
1410 for(i=sizeof(funcs); i--;)
1411 {
1412 if(d=data[i])
1413 {
1414 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1415 ARIGHT(" "+(d[2]+5)/10+"ms",10,".")+" "+
1416 ARIGHT(" "+(d[4]+5)/10+"ms",10,".")+" | "+
1417 ARIGHT(" "+d[2]/d[0]+"us",9,".")+" "+
1418 ARIGHT(" "+d[4]/d[0]+"us",9,".");
1419 }
1420 }
1421 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1422 write_file(TMP_FILE,str);
1423 XMoreFile(TMP_FILE, FALSE);
1424 }
1425 else
1426 WDLN("No profiling information available");
1427 }
1428 return TRUE;
1429}
1430
1431int Xprops(string str)
1432{
1433 int i, s, flag;
1434 object obj;
1435 string *tmp;
1436
1437 SECURE2(TRUE);
1438 USAGE2(str, "xprop(s) [-f|-m] <object>");
1439 TK("Xprops: str: "+str);
1440 tmp=old_explode(str," ");
1441 switch(tmp[0])
1442 {
1443 case "-f":
1444 {
1445 flag = 1;
1446 tmp=tmp[1..];
1447 break;
1448 }
1449 case "-m":
1450 {
1451 flag = 2;
1452 tmp=tmp[1..];
1453 break;
1454 }
1455 }
1456 str=implode(tmp," ");
1457 if((obj=XFindObj(str)))
1458 DumpProperties(obj,flag);
1459 return TRUE;
1460}
1461
1462int Xquit(string str)
1463{
1464 SECURE2(TRUE);
1465 USAGE1(str, "xqu(it)");
1466 str=object_name(ENV(cloner));
1467 if(member(str, '#')<0)
1468 cloner->set_home(str);
1469 cloner->quit();
1470 return TRUE;
1471}
1472
1473int Xscan(string str)
1474{
1475 SECURE2(TRUE);
1476 USAGE1(str, "xsc(an)");
1477 W("Destructed variable(s): ");
1478 string* oldvars=m_indices(variable);
1479 VarCheck(FALSE);
1480 string* desvars=oldvars-m_indices(variable);
1481 desvars = map(desvars, function string (string k)
1482 {return "$"+k;} );
1483 W(CountUp(desvars));
1484 WLN("");
1485 return TRUE;
1486}
1487
1488int Xset(string str)
1489{
1490 int i;
1491 mixed obj;
1492 string name, tmp;
1493
1494 SECURE2(TRUE);
1495 USAGE1(str, "xse(t) [$<name>=<object>]");
1496 if(str) {
1497 if(member(({"$me","$m","$here","$h"}),str)!=-1)
1498 WDLN("Sorry, this is a reserved variable ["+str+"]");
1499 else if(sscanf(str, "$%s=%s", name, tmp))
1500 {
1501 if(obj=XFindObj(tmp))
1502 {
1503 variable[name] = obj;
1504 WLN(" $"+name+"="+ObjFile(obj));
1505 }
1506 }
1507 else
1508 return FALSE;
1509 }
1510 else
1511 {
1512 VarCheck(FALSE);
1513 WLN("Current settings:");
1514 foreach(string key, mixed val : variable)
1515 {
1516 if (val)
1517 WLN(" $"+key+"="+ObjFile(val));
1518 else
1519 m_delete(variable, key);
1520 }
1521 WLN(" $me="+ObjFile(cloner));
1522 WLN(" $here="+ObjFile(ENV(cloner)));
1523 }
1524 return TRUE;
1525}
1526
1527int Xsh(string str)
1528{
1529 SECURE2(TRUE);
1530 USAGE1(str, "xsh <filename>");
1531 if(scriptline)
1532 {
1533 WDLN("Cannot execute another script file until last execution has ended");
1534 return TRUE;
1535 }
1536 if(!(str=XFindFile(str)))
1537 return TRUE;
1538 str=read_file(str, 1, 1000);
1539 if(!(scriptline=old_explode(str, "\n")))
1540 {
1541 WDLN("Bad script file");
1542 return TRUE;
1543 }
1544 scriptsize=sizeof(scriptline);
1545 XExecFile(NULL);
1546 return TRUE;
1547}
1548
1549int Xsort(string str)
1550{
1551 string *tmp,file;
1552 int s,reverse;
1553
1554 SECURE2(TRUE);
1555 TK("Xsort: str: "+str);
1556 if(!pipe_in)
1557 {
1558 USAGE2(str, "xso(rt) [-r] [file]");
1559 if(!(tmp=old_explode(str, " "))||(s=sizeof(tmp))>2)
1560 return FALSE;
1561 if(tmp[0]=="-r")
1562 if(s==1)
1563 return FALSE;
1564 else
1565 {
1566 reverse=TRUE;
1567 tmp=tmp[1..];
1568 }
1569 else if(s>1)
1570 return FALSE;
1571 if(!(file=XFindFile(tmp[0])))
1572 {
1573 WDLN("Can't find file");
1574 return TRUE;
1575 }
1576 }
1577 else
1578 {
1579 if(str&&str!="")
1580 if(str=="-r")
1581 reverse=TRUE;
1582 else
1583 USAGE3("xso(rt) [-r]");
1584 if (file_size(file=pipe_if)<0)
1585 {
1586 WDLN("Missing input to xsort");
1587 return TRUE;
1588 }
1589 }
1590 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
1591 if(pipe_in&&pipe_if==PIPE_FILE)
1592 rm(PIPE_FILE);
1593 tmp=sort_array(tmp,reverse?#'<:#'>);
1594 if (pipe_out&&pipe_of)
1595 write_file(pipe_of,implode(tmp,"\n")+"\n");
1596 else
1597 WDLN(implode(tmp,"\n"));
1598 return TRUE;
1599}
1600
1601int Xtail(string str)
1602{
1603 string *tmp,file,sign;
1604 int lines;
1605
1606 if (!str) {
1607 WDLN("Missing input to xtail");
1608 return TRUE;
1609 }
1610
1611 sign="-";
1612 lines=10;
1613 SECURE2(TRUE);
1614 TK("Xtail: str: "+str);
1615 if(!pipe_in)
1616 {
1617 if(sscanf(str,"-%d %s",lines,file)==2)
1618 sign="-";
1619 else if(sscanf(str,"+%d %s",lines,file)==2)
1620 sign="+";
1621 else
1622 file=str;
1623
1624 if(!(file=XFindFile(file)))
1625 {
1626 WDLN("Can't find file");
1627 return TRUE;
1628 }
1629 }
1630 else
1631 {
1632 if(sscanf(str,"-%d",lines)==1)
1633 sign="-";
1634 else if(sscanf(str,"+%d",lines)==1)
1635 sign="+";
1636 if (file_size(file=pipe_if)<0)
1637 {
1638 WDLN("Missing input to xtail");
1639 return TRUE;
1640 }
1641 }
1642
1643 if(sign=="-")
1644 {
1645 if(!lines)
1646 return TRUE;
1647 }
1648
1649 if(file_size(file)>50000)
1650 {
1651 WDLN("File too large");
1652 return TRUE;
1653 }
1654
1655 if(sign=="+")
1656 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[lines..];
1657 else
1658 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[<lines..];
1659 if(pipe_in&&pipe_if==PIPE_FILE)
1660 rm(PIPE_FILE);
1661 if (pipe_out&&pipe_of)
1662 write_file(pipe_of,implode(tmp,"\n")+"\n");
1663 else
1664 WLN(implode(tmp,"\n"));
1665 return TRUE;
1666}
1667
1668int Xtool(string str)
1669{
1670 int m;
1671 string tmp;
1672 object obj;
1673
1674 SECURE2(TRUE);
1675 TK("Xtool: str: "+str);
1676 USAGE1(str, "xto(ol) [update|first=<on|off>|protect=<on|off>|"+
1677 "invcheck=<on|off>|\n"+
1678 "\t\tvarcheck=<on|off>|scanchk=<on|off>|short=<on|off>|\n"+
1679 "\t\techo=<on|off>|more=<amount>|kill|news|save|load|reset]");
1680 if(str&&str!="")
1681 {
1682 if(sscanf(str, "more=%d", m))
1683 {
1684 if(m<5)
1685 WDLN("Sorry, amount of lines should be more then 5");
1686 else
1687 {
1688 WDLN("Setting amount of displayed lines to "+m);
1689 morelines=m;
1690 }
1691 }
1692 else
1693 switch(str)
1694 {
1695 case "update":
1696 if(obj=find_object(TOOL_PATH))
1697 Destruct(obj);
1698 if(catch(obj=clone_object(TOOL_PATH)))
1699 WLN("Updating "+TOOL_TITLE+" failed!");
1700 else
1701 obj->update_tool(AUTOLOAD_ARGS, cloner);
1702 return TRUE;
1703 break;
1704 case "first=on":
1705 MODE_ON(MODE_FIRST);
1706 move(cloner);
1707 WDLN("Automatic moving into pole position of inventory turned on");
1708 break;
1709 case "first=off":
1710 MODE_OFF(MODE_FIRST);
1711 WDLN("Automatic moving into pole position of inventory turned off");
1712 break;
1713 case "protect=on":
1714 MODE_ON(MODE_PROTECT);
1715 WDLN("Protection from forces and illegal moves turned on");
1716 break;
1717 case "protect=off":
1718 MODE_OFF(MODE_PROTECT);
1719 WDLN("Protection from forces and illegal moves turned off");
1720 break;
1721 case "invcheck=on":
1722 MODE_ON(MODE_INVCHECK);
1723 WDLN("Automatic checking for new objects in inventory turned on");
1724 break;
1725 case "invcheck=off":
1726 MODE_OFF(MODE_INVCHECK);
1727 WDLN("Automatic checking for new objects in inventory turned off");
1728 break;
1729 case "varcheck=on":
1730 MODE_ON(MODE_VARCHECK);
1731 VarCheck(TRUE);
1732 WDLN("Automatic variable checking turned on");
1733 break;
1734 case "varcheck=off":
1735 MODE_OFF(MODE_VARCHECK);
1736 WDLN("Automatic variable checking turned off");
1737 break;
1738 case "scanchk=on":
1739 MODE_ON(MODE_SCANCHK);
1740 WDLN("Scan check turned on");
1741 break;
1742 case "scanchk=off":
1743 MODE_OFF(MODE_SCANCHK);
1744 WDLN("Scan check turned off");
1745 break;
1746 case "echo=on":
1747 MODE_ON(MODE_ECHO);
1748 WDLN("Echoing of multiple command execution turned on");
1749 break;
1750 case "echo=off":
1751 MODE_OFF(MODE_ECHO);
1752 WDLN("Echoing of multiple command execution turned off");
1753 break;
1754 case "short=on":
1755 MODE_ON(MODE_SHORT);
1756 WDLN("Use of short descriptions turned on");
1757 break;
1758 case "short=off":
1759 MODE_OFF(MODE_SHORT);
1760 WDLN("Use of short descriptions turned off");
1761 break;
1762 case "kill":
1763 WDLN(TOOL_NAME+" selfdestructs");
1764 destruct(ME);
1765 break;
1766 case "news":
1767 XMoreFile(TOOL_NEWS, FALSE);
1768 break;
1769 case "reset":
1770 WDLN("Resetting "+TOOL_TITLE);
1771 ME->__INIT();
1772 break;
1773 case "load":
1774 if(file_size(SAVE_FILE+".o")>0)
1775 {
1776 WDLN("Loading "+TOOL_TITLE+" settings");
1777 restore_object(SAVE_FILE);
1778 }
1779 else
1780 WDLN("Sorry, cannot find file to load settings");
1781 break;
1782 case "save":
1783 WDLN("Saving "+TOOL_TITLE+" settings");
1784 save_object(SAVE_FILE);
1785 break;
1786 default:
1787 return FALSE;
1788 }
1789 }
1790 else
1791 {
1792 WLN(TOOL_TITLE+" settings:");
1793 tmp= (" first .... = "+(MODE(MODE_FIRST) ? "on\n" : "off\n"));
1794 tmp+=(" protect .. = "+(MODE(MODE_PROTECT) ? "on\n" : "off\n"));
1795 tmp+=(" invcheck . = "+(MODE(MODE_INVCHECK) ? "on\n" : "off\n"));
1796 tmp+=(" varcheck . = "+(MODE(MODE_VARCHECK) ? "on\n" : "off\n"));
1797 tmp+=(" scanchk .. = "+(MODE(MODE_SCANCHK) ? "on\n" : "off\n"));
1798 tmp+=(" echo ..... = "+(MODE(MODE_ECHO) ? "on\n" : "off\n"));
1799 tmp+=(" short .... = "+(MODE(MODE_SHORT) ? "on\n" : "off\n"));
1800 tmp+=(" more ..... = "+morelines);
1801 WLN(sprintf("%-80#s", tmp));
1802 }
1803 return TRUE;
1804}
1805
1806int Xtrace(string str)
1807{
1808 string file;
1809 object obj;
1810
1811 SECURE2(TRUE);
1812 USAGE1(str, "xtrac(e) <object>");
1813 if(!str||str=="")
1814 {
1815 trace(0);
1816 WDLN("Ending trace ["+short_path("/"+traceprefix(0))+"]");
1817 }
1818 else if(obj=XFindObj(str))
1819 {
1820 PrintShort("Tracing: ", obj);
1821 file=object_name(obj);
1822 file=file[1..<1];
1823 traceprefix(file);
1824 trace(TRACE_LEVEL);
1825 }
1826 return TRUE;
1827}
1828
1829int Xtrans(string str)
1830{
1831 object obj;
1832
1833 SECURE2(TRUE);
1834 USAGE2(str, "xtran(s) <object>");
1835 if((obj=XFindObj(str))&&ENV(obj))
1836 {
1837 tell_room(ENV(obj), CRNAME(obj)+" vanishes.\n");
1838 tell_room(ENV(cloner), CRNAME(obj)+
1839 " is teleported into this room by "+CRNAME(cloner)+".\n");
1840 MoveObj(obj, ENV(cloner), TRUE);
1841 tell_object(obj, "You've been teleported to "+CRNAME(cloner)+".\n");
1842 }
1843 else
1844 WDLN("Failed to teleport object");
1845 return TRUE;
1846}
1847
1848int Xupdate(string str)
1849{
1850 object obj;
1851 string file;
1852
1853 SECURE2(TRUE);
1854 USAGE2(str, "xup(date) <filename>");
1855 if(!(file=XFindFile(str)))
1856 return TRUE;
1857 if(file[<2.. <1]==".c")
1858 file=file[0.. <3];
1859 if((obj=XFindObj(file))&&(obj=find_object(pure_file_name(obj))))
1860 {
1861 PrintShort("Updating: ", obj);
1862 Destruct(obj);
1863 }
1864 else
1865 WDLN("Object not found");
1866 return TRUE;
1867}
1868
1869int Xuptime(string str)
1870{
1871 return TRUE;
1872}
1873
1874int Xwc(string str)
1875{
1876 string file;
1877 string tmp, *tmp2;
1878 int i, chars, words, lines, nchars, nwords, nlines;
1879
1880 SECURE2(TRUE);
1881 TK("Xwc: str: "+str);
1882 chars=words=lines=FALSE;
1883 if(!pipe_in)
1884 {
1885 USAGE2(str, "xwc [-cwl] <file>");
1886 if(str[0]=='-')
1887 {
1888 while((str=str[1..])[0]!=' '&&sizeof(str))
1889 switch(str[0])
1890 {
1891 case 'c':
1892 chars=TRUE;
1893 break;
1894 case 'w':
1895 words=TRUE;
1896 break;
1897 case 'l':
1898 lines=TRUE;
1899 break;
1900 default:
1901 return FALSE;
1902 }
1903 str=str[1..];
1904 }
1905 if(!(file=XFindFile(str)))
1906 {
1907 WDLN("Can't find file");
1908 return TRUE;
1909 }
1910 }
1911 else
1912 {
1913 USAGE1(str,"xwc [-cwl]");
1914 if(str)
1915 if(str[0]=='-')
1916 {
1917 while((str=str[1..])[0]!=' '&&sizeof(str))
1918 switch(str[0])
1919 {
1920 case 'c':
1921 chars=TRUE;
1922 break;
1923 case 'w':
1924 words=TRUE;
1925 break;
1926 case 'l':
1927 lines=TRUE;
1928 break;
1929 default:
1930 return FALSE;
1931 }
1932 }
1933 else
1934 return FALSE;
1935 if(file_size(file=pipe_if)<0)
1936 {
1937 WDLN("Missing input to xwc");
1938 return TRUE;
1939 }
1940 }
1941 if(!(chars|words|lines))
1942 chars=words=lines=TRUE;
1943 nlines=nwords=nchars=0;
1944 tmp=read_file(file,0,PIPE_MAX);
1945 tmp2=explode(tmp,"\n");
1946 if(lines)
1947 {
1948 nlines=sizeof(tmp2);
1949 if(tmp2[<1]==""&&nlines>1)
1950 nlines--;
1951 }
1952 if(words)
1953 for(i=sizeof(tmp2)-1;i>=0;i--)
1954 {
1955 TK(sprintf("%O",tmp2[i]));
1956 if(tmp2[i]!="")
1957 nwords+=sizeof(regexplode(tmp2[i],"[ ]")-({""," "," "}));
1958 TK(sprintf("%O",regexplode(tmp2[i],"[ ]")-({""," "," "})));
1959 TK("nwords: "+nwords);
1960 }
1961 if(chars)
1962 for(i=sizeof(tmp2)-1;i>=0;i--)
1963 nchars+=sizeof(tmp2[i])+1;
1964 tmp2=0;
1965 tmp="";
1966 if(lines)
1967 tmp+=sprintf("%7d",nlines)+" ";
1968 if(words)
1969 tmp+=sprintf("%7d",nwords)+" ";
1970 if(chars)
1971 tmp+=sprintf("%7d",nchars)+" ";
1972 if(file!=pipe_if)
1973 tmp+=file;
1974 WLN(tmp);
1975 return TRUE;
1976}
1977
1978int cmdavg_compare(string a, string b)
1979{
1980 int x,y;
1981 string dum;
1982 sscanf(a,"%s cmdavg: %d",dum,x);
1983 sscanf(b,"%s cmdavg: %d",dum,y);
1984 return x==y?0:(x>y?1:-1);
1985}
1986
1987int Xwho(string opt)
1988{
1989 string *strs,str,func;
1990
1991 SECURE2(TRUE);
1992 TK("Xwho: opt: \""+opt+"\"");
1993 USAGE1(opt, "xwh(o) [mail|ip|race|guild|domain|stats|snoop]");
1994 func="string_compare";
1995 if(!opt||opt=="")
1996 strs=map(users(), "PlayerWho", ME);
1997 else
1998 switch(opt)
1999 {
2000 case "mail":
2001 strs=map(users(), "PlayerMail", ME, TRUE);
2002 break;
2003 case "ip":
2004 strs=map(users(), "PlayerIP", ME, TRUE);
2005 break;
2006 case "race":
2007 case "guild":
2008 strs=map(users(), "PlayerRace", ME, TRUE);
2009 break;
2010 case "domain":
2011 strs=map(users(), "PlayerDomain", ME, TRUE);
2012 break;
2013 case "stat":
2014 case "stats":
2015 strs=map(users(), "PlayerStats", ME, TRUE);
2016 break;
2017 case "snoop":
2018 strs=map(users(), "PlayerSnoop", ME, TRUE);
2019 break;
2020 case "cmdavg":
2021 strs=map(users(), "PlayerCmdAvg", ME, TRUE);
2022 func="cmdavg_compare";
2023 break;
2024 default:
2025 return FALSE;
2026 }
2027 strs=sort_array(strs, func, ME);
2028 if(pipe_out&&pipe_of)
2029 write_file(pipe_of,implode(strs,"\n")+"\n");
2030 else
2031 WLN(implode(strs,"\n"));
2032 return TRUE;
2033}