blob: e2546c10933cf72293f9c78a2a0a69e5e4b754c4 [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();
bugfixaf2be4f2020-03-22 19:13:07 +010063 error=catch(res=obj->eval(callobj, cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +020064 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 {
bugfixaf2be4f2020-03-22 19:13:07 +0100186 if(!(path=cloner->QueryProp("start_home")))
MG Mud User88f12472016-06-24 23:31:02 +0200187 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();
bugfixaf2be4f2020-03-22 19:13:07 +0100490 error=catch(res=obj->eval(cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +0200491 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
Zesstrabc791ab2017-01-30 23:06:48 +0100952 if(!(daemon=load_object(LAG_O_DAEMON)))
MG Mud User88f12472016-06-24 23:31:02 +0200953 lag=({-1.0,-1.0,-1.0});
954 else
bugfixaf2be4f2020-03-22 19:13:07 +0100955 lag=daemon->read_lag_data();
MG Mud User88f12472016-06-24 23:31:02 +0200956 lags="Letzte 60 min: ";
957 if(lag[0]>=0.0)
958 {
959 for(i=round(lag[0])-1;i>=0;i--)
960 lags+="#";
961 lags+=" ("+sprintf("%.1f",lag[0])+"%)";
962 }
963 else
964 lags+="N/A";
965 lags+="\nLetzte 15 min: ";
966 if(lag[1]>=0.0)
967 {
968 for(i=round(lag[1])-1;i>=0;i--)
969 lags+="#";
970 lags+=" ("+sprintf("%.1f",lag[1])+"%)";
971 }
972 else
973 lags+="N/A";
974 lags+="\nLetzte Minute: ";
975 if(lag[2]>=0.0)
976 {
977 for(i=round(lag[2])-1;i>=0;i--)
978 lags+="#";
979 lags+=" ("+sprintf("%.1f",lag[2])+"%)";
980 }
981 else
982 lags+="N/A";
983 WLN(lags);
984 return TRUE;
985}
986
987int Xlight(string str)
988{
989 int s, addlight;
990
991 SECURE2(TRUE);
992 USAGE1(str, "xli(ght) [light]");
993 if(str)
994 {
995 if(!sscanf(str, "%d", addlight))
996 return FALSE;
997 xlight+=addlight;
998 cloner->AddIntLight(addlight);
999 }
1000 WDLN("Current light levels: "+TOOL_NAME+"="+xlight+", room="+
1001 ENV(cloner)->QueryIntLight());
1002 return TRUE;
1003}
1004
1005int Xload(string str)
1006{
1007 int i, f;
1008 object obj, *inv, vroom;
1009 string file, errlog, error, *strs;
1010
1011 SECURE2(TRUE);
1012 USAGE2(str, "xloa(d) <filename>");
1013 if(!(file=XFindFile(str)))
1014 return TRUE;
1015 errlog=ERR_FILE;
1016 if(file_size(errlog)>0)
1017 rm(errlog);
1018 if(obj=find_object(file))
1019 {
1020 if(catch(call_other(VOID, "???")))
1021 {
1022 WDLN("Error: cannot find "+VOID+" to rescue players");
1023 return TRUE;
1024 }
1025 else
1026 vroom = find_object(VOID);
1027 if(inv=filter(all_inventory(obj), #'is_player, ME))//'
1028 for(i=0; i<sizeof(inv); i++)
1029 MoveObj(inv[i], vroom, TRUE);
1030 Destruct(obj);
1031 WLN("Update and load: "+file);
1032 }
1033 else
1034 WLN("Load: "+file);
1035 if(error=catch(call_other(file, "???")))
1036 {
1037 W("Error: "+error[1..]);
1038 if(vroom)
1039 tell_object(vroom, "*** Failed to load room. You are in the void!\n");
1040 }
1041 else if(inv)
1042 {
1043 obj=find_object(file);
1044 for(i=0; i<sizeof(inv); i++)
1045 if(inv[i])
1046 MoveObj(inv[i], obj, TRUE);
1047 }
1048 return TRUE;
1049}
1050
1051int Xlook(string str)
1052{
1053 object obj;
1054 string st;
1055 string file;
1056
1057 SECURE2(TRUE);
1058 USAGE1(str, "xloo(k) [object]");
1059 TK("Xlook: str: "+str);
1060 PIPE_DELETE(pipe_of);
1061 file = pipe_out&&pipe_of ? pipe_of : "";
1062 if(str&&str!="")
1063 {
1064 if((obj=XFindObj(str)))
1065 PrintObj(obj,file);
1066 }
1067 else
1068 {
1069 obj=ENV(cloner);
1070 PrintObj(obj,file);
1071 }
1072 return TRUE;
1073}
1074
1075int Xlpc(string str)
1076{
1077 object obj;
1078 string file, error;
1079 int *ru1, *ru2, time;
1080 mixed res;
1081
1082 SECURE2(TRUE);
1083 USAGE2(str, "xlp(c) <lpc code>");
1084 file=LPC_FILE+".c";
1085 if(file_size(file)>0)
1086 rm(file);
1087 if(obj=find_object(LPC_FILE))
1088 Destruct(obj);
1089 write_file(file,
1090 "#pragma no_warn_missing_return,strong_types,warn_deprecated,rtt_checks\n"
1091 "#include <properties.h>\n"
1092 "#include <thing/properties.h>\n"
1093 "#include <defines.h>\n"
1094 "#include <wizlist.h>\n"
1095 "#include <moving.h>\n"
1096 "#include \"/secure/wizlevels.h\"\n"
1097 +(file_size(PRIVATE_HEADER)>=0?"#include \""+PRIVATE_HEADER+"\"\n":"")+
1098 "object get(string str){return previous_object()->XFindObj(str);}\n"+
1099 "mixed eval(mixed me, mixed here){"+str+"}");
1100 if(error=catch(obj=clone_object(file)))
1101 W("Error: "+error[1..0]);
1102 else
1103 {
1104 ru1=rusage();
bugfixaf2be4f2020-03-22 19:13:07 +01001105 error=catch(res=obj->eval(cloner, ENV(cloner)));
MG Mud User88f12472016-06-24 23:31:02 +02001106 ru2=rusage();
1107 if(error)
1108 W("Error: "+error[1..]);
1109 else
1110 {
1111 time=ru2[0]-ru1[0]+ru2[1]-ru1[1];
1112 WDLN("Evaluation time: "+(time<0 ? 0 : time)+" ms");
1113 WLN("Result: "+mixed_to_string(res, MAX_RECURSION));
1114 if(objectp(res))
1115 variable["result"] = res;
1116 }
1117 }
1118 rm(file);
1119 if(obj)
1120 Destruct(obj);
1121 return TRUE;
1122}
1123
1124int Xman(string str)
1125{
1126 string manpage;
1127 int i, found;
1128
1129 SECURE2(TRUE);
1130 USAGE2(str, "xma(n) <manpage>");
1131 W("Man: ");
1132 for(i=0, found=0; i<sizeof(manpath); i++)
1133 {
1134 manpage=manpath[i]+str;
1135 if(file_size(manpage)>=0)
1136 {
1137 WLN(manpage);
1138 XMoreFile(manpage, FALSE);
1139 found=1;
1140 break;
1141 }
1142 }
1143 if(!found)
1144 WLN("- no help available -");
1145 return TRUE;
1146}
1147
1148int Xmore(string str)
1149{
1150 string *args, file;
1151 int line;
1152
1153 SECURE2(TRUE);
1154 TK("Xmore: str: "+str);
1155 if (!pipe_in)
1156 {
1157 USAGE2(str, "xmor(e) <filename> [start]");
1158 switch(sizeof(args=strip_explode(str, " ")))
1159 {
1160 case 1:
1161 moreoffset=1;
1162 break;
1163 case 2:
1164 sscanf(args[1], "%d", line);
1165 moreoffset= line>0 ? line : 1;
1166 break;
1167 default:
1168 return FALSE;
1169 }
1170 if(file=XFindFile(args[0]))
1171 XMoreFile(file, TRUE);
1172 }
1173 else
1174 {
1175 if(file_size(pipe_if)<0)
1176 {
1177 WDLN("Missing input to xmore");
1178 return TRUE;
1179 }
1180 if (!str||str=="")
1181 line=1;
1182 else if (sscanf(str, "%d", line)!=1)
1183 USAGE3("xmor(e) [start]");
1184 moreoffset= line>0 ? line : 1;
1185 XMoreFile(pipe_if, TRUE);
1186 }
1187 return TRUE;
1188}
1189
1190int Xmove(string str)
1191{
1192 object obj1, obj2;
1193 string what, into;
1194
1195 SECURE2(TRUE);
1196 USAGE2(str, "xmov(e) <object> into <object>");
1197 if((sscanf(str, "%s into %s", what, into)==2)&&
1198 (obj1=XFindObj(what))&&(obj2=XFindObj(into)))
1199 MoveObj(obj1, obj2, FALSE);
1200 return TRUE;
1201}
1202
1203int Xmsg(string str)
1204{
1205 string tmp;
1206
1207 SECURE2(TRUE);
1208 TK("Xmsg: str: "+str);
1209 USAGE1(str, "xms(g) [to <object>|all]");
1210 if(!str||str=="")
1211 {
1212 WDLN("Send message into room");
1213 say("Message from "+CRNAME(cloner)+":\n");
1214 if(pipe_in&&pipe_if)
1215 say(read_file(pipe_if,0,PIPE_MAX));
1216 else
1217 {
1218 WDLN("End message with \".\" or \"**\"");
1219 input_to("XMsgSay");
1220 }
1221 return TRUE;
1222 }
1223 else if(sscanf(str, "to %s", tmp))
1224 {
1225 if(msgto=XFindObj(tmp))
1226 {
1227 PrintShort("Send message to: ", msgto);
1228 tell_object(msgto, "Message from "+CRNAME(cloner)+" to you:\n");
1229 if(pipe_in&&pipe_if)
1230 tell_object(msgto,read_file(pipe_if,0,PIPE_MAX));
1231 else
1232 {
1233 WDLN("End message with \".\" or \"**\"");
1234 input_to("XMsgTell");
1235 }
1236 }
1237 return TRUE;
1238 }
1239 else if(str=="all")
1240 {
1241 WDLN("Send message to all players");
1242 shout("Message from "+CRNAME(cloner)+" to all:\n");
1243 if(pipe_in&&pipe_if)
1244 shout(read_file(pipe_if,0,PIPE_MAX));
1245 else
1246 {
1247 WDLN("End message with \".\" or \"**\"");
1248 input_to("XMsgShout");
1249 }
1250 return TRUE;
1251 }
1252 return FALSE;
1253}
1254
1255int Xmtp(string str)
1256{
1257 int s;
1258 string *strs, opt, dir, file;
1259
1260 SECURE2(TRUE);
1261 USAGE2(str, "xmt(p) [options] <directory> <filename>");
1262 s=sizeof(strs=old_explode(str, " "));
1263 if(s<2)
1264 return FALSE;
1265 else if(s==2)
1266 opt="";
1267 else
1268 opt=implode(strs[0..s-3], " ");
bugfixaf2be4f2020-03-22 19:13:07 +01001269 if(!(dir="/"+MASTER->valid_read(strs[s-2], geteuid(),
MG Mud User88f12472016-06-24 23:31:02 +02001270 "get_dir", ME))) {
1271 WDLN("No permission to open directory for reading");
1272 return TRUE;
1273 }
bugfixaf2be4f2020-03-22 19:13:07 +01001274 if(!(file="/"+MASTER->valid_write(strs[s-1], geteuid(),
MG Mud User88f12472016-06-24 23:31:02 +02001275 "write_file", ME))) {
1276 WDLN("No permission to open script file for writing");
1277 return TRUE;
1278 }
1279 if(file_size(dir)!=-2 || file_size(file)==-2)
1280 return FALSE;
1281 XmtpScript(dir, file, opt);
1282 WDLN("Done");
1283 return TRUE;
1284}
1285
1286int Xproc(string str)
1287{
1288 int s;
1289 string *strs;
1290
1291 SECURE2(TRUE);
1292 USAGE1(str, "xproc [-c] [-l] [-m] [-u] [-v]");
1293
1294 if(file_size(TOOL_PATH+"/proc")!=-2)
1295 {
1296 WLN("Sorry, no /proc information available!");
1297 return TRUE;
1298 }
1299
1300 if(!str||str==""||!(s=sizeof(strs=old_explode(str, " "))))
1301 {
1302 WLN("Load averages:");
1303 cat(TOOL_PATH+"/proc/loadavg");
1304 return TRUE;
1305 }
1306
1307 while(s=sizeof(strs))
1308 {
1309 switch(strs[0])
1310 {
1311 case "-c":
1312 WLN("CPU info:");
1313 cat(TOOL_PATH+"/proc/cpuinfo");
1314 break;
1315 case "-l":
1316 WLN("Load averages:");
1317 cat(TOOL_PATH+"/proc/loadavg");
1318 break;
1319 case "-m":
1320 WLN("Memory usage:");
1321 cat(TOOL_PATH+"/proc/meminfo");
1322 break;
1323 case "-u":
1324 WLN("Uptime:");
1325 cat(TOOL_PATH+"/proc/uptime");
1326 break;
1327 case "-v":
1328 WLN("Version:");
1329 cat(TOOL_PATH+"/proc/version");
1330 break;
1331 default:
1332 WLN("Unknown option: "+strs[0]);
1333 }
1334 strs=strs[1..];
1335 }
1336 return TRUE;
1337}
1338
1339int Xprof(string str)
1340{
1341 string *funcs, inh, tmp;
1342 mixed *data, *d;
1343 mapping xpr;
1344 object obj;
1345 int i, rn;
1346
1347 SECURE2(TRUE);
1348 USAGE2(str, "xprof <<-c>|<-C> <file>>|<object>");
1349 if(str[0..2]=="-c "||str[0..2]=="-C ")
1350 {
1351 rn=(str[1]=='C');
1352 if(str=XFindFile(str[3..]))
1353 {
1354 inh=str=str[0..<3];
1355 if(obj=find_object(inh))
1356 Destruct(obj);
1357 if(catch(call_other(inh,"???")))
1358 return TRUE;
1359 obj=find_object(inh);
1360 if(rn)
1361 {
1362 inh+=".xprof.c";
1363 rm(inh);
1364 str+=".c";
1365 rename(str, inh);
1366 }
1367 else
1368 {
1369 str=XPROF_FILE;
1370 rm(str);
1371 }
1372 tmp="inherit \""+inh+"\";\n#include \""+XPROF_MACRO+"\"\n";
1373 funcs=m_indices(mkmapping(functionlist(obj, 0x08000001)))-({"__INIT"});
1374 for(i=sizeof(funcs); i--;)
1375 tmp+="F("+funcs[i]+",\""+funcs[i]+"\","+
1376 "(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9))\n";
1377 write_file(str, tmp);
1378 WDLN("Done");
1379 }
1380 }
1381 else if(obj=XFindObj(str))
1382 {
bugfixaf2be4f2020-03-22 19:13:07 +01001383 if(xpr=obj->__query_xprof_data__())
MG Mud User88f12472016-06-24 23:31:02 +02001384 {
1385 funcs=m_indices(xpr);
1386 data=m_values(xpr);
1387 rm(TMP_FILE);
1388 str="Evaluation cost per function:\nNAME "+
1389 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1390 for(i=sizeof(funcs); i--;)
1391 {
1392 if(d=data[i]) {
1393 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1394 ARIGHT(" "+d[1],10,".") +" "+ARIGHT(" "+d[3],10,".")+" | "+
1395 ARIGHT(" "+d[1]/d[0],9,".") +" "+ARIGHT(" "+d[3]/d[0],9,".");
1396 }
1397 }
1398 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1399 write_file(TMP_FILE,str);
1400 str="\nElapsed time per function:\nNAME "+
1401 " CALLS | TOT.EXCL. TOT.INCL. | REL.EXCL. REL.INCL.\n";
1402 funcs=m_indices(xpr);
1403 for(i=sizeof(funcs); i--;)
1404 {
1405 if(d=data[i])
1406 {
1407 funcs[i]=ALEFT(""+funcs[i]+" ",25,".")+ARIGHT(" "+d[0], 6,".")+" | "+
1408 ARIGHT(" "+(d[2]+5)/10+"ms",10,".")+" "+
1409 ARIGHT(" "+(d[4]+5)/10+"ms",10,".")+" | "+
1410 ARIGHT(" "+d[2]/d[0]+"us",9,".")+" "+
1411 ARIGHT(" "+d[4]/d[0]+"us",9,".");
1412 }
1413 }
1414 str+=implode(sort_array(funcs, "string_compare", ME),"\n")+"\n";
1415 write_file(TMP_FILE,str);
1416 XMoreFile(TMP_FILE, FALSE);
1417 }
1418 else
1419 WDLN("No profiling information available");
1420 }
1421 return TRUE;
1422}
1423
1424int Xprops(string str)
1425{
1426 int i, s, flag;
1427 object obj;
1428 string *tmp;
1429
1430 SECURE2(TRUE);
1431 USAGE2(str, "xprop(s) [-f|-m] <object>");
1432 TK("Xprops: str: "+str);
1433 tmp=old_explode(str," ");
1434 switch(tmp[0])
1435 {
1436 case "-f":
1437 {
1438 flag = 1;
1439 tmp=tmp[1..];
1440 break;
1441 }
1442 case "-m":
1443 {
1444 flag = 2;
1445 tmp=tmp[1..];
1446 break;
1447 }
1448 }
1449 str=implode(tmp," ");
1450 if((obj=XFindObj(str)))
1451 DumpProperties(obj,flag);
1452 return TRUE;
1453}
1454
1455int Xquit(string str)
1456{
1457 SECURE2(TRUE);
1458 USAGE1(str, "xqu(it)");
1459 str=object_name(ENV(cloner));
1460 if(member(str, '#')<0)
1461 cloner->set_home(str);
1462 cloner->quit();
1463 return TRUE;
1464}
1465
1466int Xscan(string str)
1467{
1468 SECURE2(TRUE);
1469 USAGE1(str, "xsc(an)");
1470 W("Destructed variable(s): ");
1471 string* oldvars=m_indices(variable);
1472 VarCheck(FALSE);
1473 string* desvars=oldvars-m_indices(variable);
1474 desvars = map(desvars, function string (string k)
1475 {return "$"+k;} );
1476 W(CountUp(desvars));
1477 WLN("");
1478 return TRUE;
1479}
1480
1481int Xset(string str)
1482{
1483 int i;
1484 mixed obj;
1485 string name, tmp;
1486
1487 SECURE2(TRUE);
1488 USAGE1(str, "xse(t) [$<name>=<object>]");
1489 if(str) {
1490 if(member(({"$me","$m","$here","$h"}),str)!=-1)
1491 WDLN("Sorry, this is a reserved variable ["+str+"]");
1492 else if(sscanf(str, "$%s=%s", name, tmp))
1493 {
1494 if(obj=XFindObj(tmp))
1495 {
1496 variable[name] = obj;
1497 WLN(" $"+name+"="+ObjFile(obj));
1498 }
1499 }
1500 else
1501 return FALSE;
1502 }
1503 else
1504 {
1505 VarCheck(FALSE);
1506 WLN("Current settings:");
1507 foreach(string key, mixed val : variable)
1508 {
1509 if (val)
1510 WLN(" $"+key+"="+ObjFile(val));
1511 else
1512 m_delete(variable, key);
1513 }
1514 WLN(" $me="+ObjFile(cloner));
1515 WLN(" $here="+ObjFile(ENV(cloner)));
1516 }
1517 return TRUE;
1518}
1519
1520int Xsh(string str)
1521{
1522 SECURE2(TRUE);
1523 USAGE1(str, "xsh <filename>");
1524 if(scriptline)
1525 {
1526 WDLN("Cannot execute another script file until last execution has ended");
1527 return TRUE;
1528 }
1529 if(!(str=XFindFile(str)))
1530 return TRUE;
1531 str=read_file(str, 1, 1000);
1532 if(!(scriptline=old_explode(str, "\n")))
1533 {
1534 WDLN("Bad script file");
1535 return TRUE;
1536 }
1537 scriptsize=sizeof(scriptline);
1538 XExecFile(NULL);
1539 return TRUE;
1540}
1541
1542int Xsort(string str)
1543{
1544 string *tmp,file;
1545 int s,reverse;
1546
1547 SECURE2(TRUE);
1548 TK("Xsort: str: "+str);
1549 if(!pipe_in)
1550 {
1551 USAGE2(str, "xso(rt) [-r] [file]");
1552 if(!(tmp=old_explode(str, " "))||(s=sizeof(tmp))>2)
1553 return FALSE;
1554 if(tmp[0]=="-r")
1555 if(s==1)
1556 return FALSE;
1557 else
1558 {
1559 reverse=TRUE;
1560 tmp=tmp[1..];
1561 }
1562 else if(s>1)
1563 return FALSE;
1564 if(!(file=XFindFile(tmp[0])))
1565 {
1566 WDLN("Can't find file");
1567 return TRUE;
1568 }
1569 }
1570 else
1571 {
1572 if(str&&str!="")
1573 if(str=="-r")
1574 reverse=TRUE;
1575 else
1576 USAGE3("xso(rt) [-r]");
1577 if (file_size(file=pipe_if)<0)
1578 {
1579 WDLN("Missing input to xsort");
1580 return TRUE;
1581 }
1582 }
1583 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n");
1584 if(pipe_in&&pipe_if==PIPE_FILE)
1585 rm(PIPE_FILE);
1586 tmp=sort_array(tmp,reverse?#'<:#'>);
1587 if (pipe_out&&pipe_of)
1588 write_file(pipe_of,implode(tmp,"\n")+"\n");
1589 else
1590 WDLN(implode(tmp,"\n"));
1591 return TRUE;
1592}
1593
1594int Xtail(string str)
1595{
1596 string *tmp,file,sign;
1597 int lines;
1598
1599 if (!str) {
1600 WDLN("Missing input to xtail");
1601 return TRUE;
1602 }
1603
1604 sign="-";
1605 lines=10;
1606 SECURE2(TRUE);
1607 TK("Xtail: str: "+str);
1608 if(!pipe_in)
1609 {
1610 if(sscanf(str,"-%d %s",lines,file)==2)
1611 sign="-";
1612 else if(sscanf(str,"+%d %s",lines,file)==2)
1613 sign="+";
1614 else
1615 file=str;
1616
1617 if(!(file=XFindFile(file)))
1618 {
1619 WDLN("Can't find file");
1620 return TRUE;
1621 }
1622 }
1623 else
1624 {
1625 if(sscanf(str,"-%d",lines)==1)
1626 sign="-";
1627 else if(sscanf(str,"+%d",lines)==1)
1628 sign="+";
1629 if (file_size(file=pipe_if)<0)
1630 {
1631 WDLN("Missing input to xtail");
1632 return TRUE;
1633 }
1634 }
1635
1636 if(sign=="-")
1637 {
1638 if(!lines)
1639 return TRUE;
1640 }
1641
1642 if(file_size(file)>50000)
1643 {
1644 WDLN("File too large");
1645 return TRUE;
1646 }
1647
1648 if(sign=="+")
1649 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[lines..];
1650 else
1651 tmp=old_explode(read_file(file,0,PIPE_MAX),"\n")[<lines..];
1652 if(pipe_in&&pipe_if==PIPE_FILE)
1653 rm(PIPE_FILE);
1654 if (pipe_out&&pipe_of)
1655 write_file(pipe_of,implode(tmp,"\n")+"\n");
1656 else
1657 WLN(implode(tmp,"\n"));
1658 return TRUE;
1659}
1660
1661int Xtool(string str)
1662{
1663 int m;
1664 string tmp;
1665 object obj;
1666
1667 SECURE2(TRUE);
1668 TK("Xtool: str: "+str);
1669 USAGE1(str, "xto(ol) [update|first=<on|off>|protect=<on|off>|"+
1670 "invcheck=<on|off>|\n"+
1671 "\t\tvarcheck=<on|off>|scanchk=<on|off>|short=<on|off>|\n"+
1672 "\t\techo=<on|off>|more=<amount>|kill|news|save|load|reset]");
1673 if(str&&str!="")
1674 {
1675 if(sscanf(str, "more=%d", m))
1676 {
1677 if(m<5)
1678 WDLN("Sorry, amount of lines should be more then 5");
1679 else
1680 {
1681 WDLN("Setting amount of displayed lines to "+m);
1682 morelines=m;
1683 }
1684 }
1685 else
1686 switch(str)
1687 {
1688 case "update":
1689 if(obj=find_object(TOOL_PATH))
1690 Destruct(obj);
1691 if(catch(obj=clone_object(TOOL_PATH)))
1692 WLN("Updating "+TOOL_TITLE+" failed!");
1693 else
1694 obj->update_tool(AUTOLOAD_ARGS, cloner);
1695 return TRUE;
1696 break;
1697 case "first=on":
1698 MODE_ON(MODE_FIRST);
1699 move(cloner);
1700 WDLN("Automatic moving into pole position of inventory turned on");
1701 break;
1702 case "first=off":
1703 MODE_OFF(MODE_FIRST);
1704 WDLN("Automatic moving into pole position of inventory turned off");
1705 break;
1706 case "protect=on":
1707 MODE_ON(MODE_PROTECT);
1708 WDLN("Protection from forces and illegal moves turned on");
1709 break;
1710 case "protect=off":
1711 MODE_OFF(MODE_PROTECT);
1712 WDLN("Protection from forces and illegal moves turned off");
1713 break;
1714 case "invcheck=on":
1715 MODE_ON(MODE_INVCHECK);
1716 WDLN("Automatic checking for new objects in inventory turned on");
1717 break;
1718 case "invcheck=off":
1719 MODE_OFF(MODE_INVCHECK);
1720 WDLN("Automatic checking for new objects in inventory turned off");
1721 break;
1722 case "varcheck=on":
1723 MODE_ON(MODE_VARCHECK);
1724 VarCheck(TRUE);
1725 WDLN("Automatic variable checking turned on");
1726 break;
1727 case "varcheck=off":
1728 MODE_OFF(MODE_VARCHECK);
1729 WDLN("Automatic variable checking turned off");
1730 break;
1731 case "scanchk=on":
1732 MODE_ON(MODE_SCANCHK);
1733 WDLN("Scan check turned on");
1734 break;
1735 case "scanchk=off":
1736 MODE_OFF(MODE_SCANCHK);
1737 WDLN("Scan check turned off");
1738 break;
1739 case "echo=on":
1740 MODE_ON(MODE_ECHO);
1741 WDLN("Echoing of multiple command execution turned on");
1742 break;
1743 case "echo=off":
1744 MODE_OFF(MODE_ECHO);
1745 WDLN("Echoing of multiple command execution turned off");
1746 break;
1747 case "short=on":
1748 MODE_ON(MODE_SHORT);
1749 WDLN("Use of short descriptions turned on");
1750 break;
1751 case "short=off":
1752 MODE_OFF(MODE_SHORT);
1753 WDLN("Use of short descriptions turned off");
1754 break;
1755 case "kill":
1756 WDLN(TOOL_NAME+" selfdestructs");
1757 destruct(ME);
1758 break;
1759 case "news":
1760 XMoreFile(TOOL_NEWS, FALSE);
1761 break;
1762 case "reset":
1763 WDLN("Resetting "+TOOL_TITLE);
1764 ME->__INIT();
1765 break;
1766 case "load":
1767 if(file_size(SAVE_FILE+".o")>0)
1768 {
1769 WDLN("Loading "+TOOL_TITLE+" settings");
1770 restore_object(SAVE_FILE);
1771 }
1772 else
1773 WDLN("Sorry, cannot find file to load settings");
1774 break;
1775 case "save":
1776 WDLN("Saving "+TOOL_TITLE+" settings");
1777 save_object(SAVE_FILE);
1778 break;
1779 default:
1780 return FALSE;
1781 }
1782 }
1783 else
1784 {
1785 WLN(TOOL_TITLE+" settings:");
1786 tmp= (" first .... = "+(MODE(MODE_FIRST) ? "on\n" : "off\n"));
1787 tmp+=(" protect .. = "+(MODE(MODE_PROTECT) ? "on\n" : "off\n"));
1788 tmp+=(" invcheck . = "+(MODE(MODE_INVCHECK) ? "on\n" : "off\n"));
1789 tmp+=(" varcheck . = "+(MODE(MODE_VARCHECK) ? "on\n" : "off\n"));
1790 tmp+=(" scanchk .. = "+(MODE(MODE_SCANCHK) ? "on\n" : "off\n"));
1791 tmp+=(" echo ..... = "+(MODE(MODE_ECHO) ? "on\n" : "off\n"));
1792 tmp+=(" short .... = "+(MODE(MODE_SHORT) ? "on\n" : "off\n"));
1793 tmp+=(" more ..... = "+morelines);
1794 WLN(sprintf("%-80#s", tmp));
1795 }
1796 return TRUE;
1797}
1798
1799int Xtrace(string str)
1800{
1801 string file;
1802 object obj;
1803
1804 SECURE2(TRUE);
1805 USAGE1(str, "xtrac(e) <object>");
1806 if(!str||str=="")
1807 {
1808 trace(0);
1809 WDLN("Ending trace ["+short_path("/"+traceprefix(0))+"]");
1810 }
1811 else if(obj=XFindObj(str))
1812 {
1813 PrintShort("Tracing: ", obj);
1814 file=object_name(obj);
1815 file=file[1..<1];
1816 traceprefix(file);
1817 trace(TRACE_LEVEL);
1818 }
1819 return TRUE;
1820}
1821
1822int Xtrans(string str)
1823{
1824 object obj;
1825
1826 SECURE2(TRUE);
1827 USAGE2(str, "xtran(s) <object>");
1828 if((obj=XFindObj(str))&&ENV(obj))
1829 {
1830 tell_room(ENV(obj), CRNAME(obj)+" vanishes.\n");
1831 tell_room(ENV(cloner), CRNAME(obj)+
1832 " is teleported into this room by "+CRNAME(cloner)+".\n");
1833 MoveObj(obj, ENV(cloner), TRUE);
1834 tell_object(obj, "You've been teleported to "+CRNAME(cloner)+".\n");
1835 }
1836 else
1837 WDLN("Failed to teleport object");
1838 return TRUE;
1839}
1840
1841int Xupdate(string str)
1842{
1843 object obj;
1844 string file;
1845
1846 SECURE2(TRUE);
1847 USAGE2(str, "xup(date) <filename>");
1848 if(!(file=XFindFile(str)))
1849 return TRUE;
1850 if(file[<2.. <1]==".c")
1851 file=file[0.. <3];
1852 if((obj=XFindObj(file))&&(obj=find_object(pure_file_name(obj))))
1853 {
1854 PrintShort("Updating: ", obj);
1855 Destruct(obj);
1856 }
1857 else
1858 WDLN("Object not found");
1859 return TRUE;
1860}
1861
1862int Xuptime(string str)
1863{
1864 return TRUE;
1865}
1866
1867int Xwc(string str)
1868{
1869 string file;
1870 string tmp, *tmp2;
1871 int i, chars, words, lines, nchars, nwords, nlines;
1872
1873 SECURE2(TRUE);
1874 TK("Xwc: str: "+str);
1875 chars=words=lines=FALSE;
1876 if(!pipe_in)
1877 {
1878 USAGE2(str, "xwc [-cwl] <file>");
1879 if(str[0]=='-')
1880 {
1881 while((str=str[1..])[0]!=' '&&sizeof(str))
1882 switch(str[0])
1883 {
1884 case 'c':
1885 chars=TRUE;
1886 break;
1887 case 'w':
1888 words=TRUE;
1889 break;
1890 case 'l':
1891 lines=TRUE;
1892 break;
1893 default:
1894 return FALSE;
1895 }
1896 str=str[1..];
1897 }
1898 if(!(file=XFindFile(str)))
1899 {
1900 WDLN("Can't find file");
1901 return TRUE;
1902 }
1903 }
1904 else
1905 {
1906 USAGE1(str,"xwc [-cwl]");
1907 if(str)
1908 if(str[0]=='-')
1909 {
1910 while((str=str[1..])[0]!=' '&&sizeof(str))
1911 switch(str[0])
1912 {
1913 case 'c':
1914 chars=TRUE;
1915 break;
1916 case 'w':
1917 words=TRUE;
1918 break;
1919 case 'l':
1920 lines=TRUE;
1921 break;
1922 default:
1923 return FALSE;
1924 }
1925 }
1926 else
1927 return FALSE;
1928 if(file_size(file=pipe_if)<0)
1929 {
1930 WDLN("Missing input to xwc");
1931 return TRUE;
1932 }
1933 }
1934 if(!(chars|words|lines))
1935 chars=words=lines=TRUE;
1936 nlines=nwords=nchars=0;
1937 tmp=read_file(file,0,PIPE_MAX);
1938 tmp2=explode(tmp,"\n");
1939 if(lines)
1940 {
1941 nlines=sizeof(tmp2);
1942 if(tmp2[<1]==""&&nlines>1)
1943 nlines--;
1944 }
1945 if(words)
1946 for(i=sizeof(tmp2)-1;i>=0;i--)
1947 {
1948 TK(sprintf("%O",tmp2[i]));
1949 if(tmp2[i]!="")
1950 nwords+=sizeof(regexplode(tmp2[i],"[ ]")-({""," "," "}));
1951 TK(sprintf("%O",regexplode(tmp2[i],"[ ]")-({""," "," "})));
1952 TK("nwords: "+nwords);
1953 }
1954 if(chars)
1955 for(i=sizeof(tmp2)-1;i>=0;i--)
1956 nchars+=sizeof(tmp2[i])+1;
1957 tmp2=0;
1958 tmp="";
1959 if(lines)
1960 tmp+=sprintf("%7d",nlines)+" ";
1961 if(words)
1962 tmp+=sprintf("%7d",nwords)+" ";
1963 if(chars)
1964 tmp+=sprintf("%7d",nchars)+" ";
1965 if(file!=pipe_if)
1966 tmp+=file;
1967 WLN(tmp);
1968 return TRUE;
1969}
1970
1971int cmdavg_compare(string a, string b)
1972{
1973 int x,y;
1974 string dum;
1975 sscanf(a,"%s cmdavg: %d",dum,x);
1976 sscanf(b,"%s cmdavg: %d",dum,y);
1977 return x==y?0:(x>y?1:-1);
1978}
1979
1980int Xwho(string opt)
1981{
1982 string *strs,str,func;
1983
1984 SECURE2(TRUE);
1985 TK("Xwho: opt: \""+opt+"\"");
1986 USAGE1(opt, "xwh(o) [mail|ip|race|guild|domain|stats|snoop]");
1987 func="string_compare";
1988 if(!opt||opt=="")
1989 strs=map(users(), "PlayerWho", ME);
1990 else
1991 switch(opt)
1992 {
1993 case "mail":
1994 strs=map(users(), "PlayerMail", ME, TRUE);
1995 break;
1996 case "ip":
1997 strs=map(users(), "PlayerIP", ME, TRUE);
1998 break;
1999 case "race":
2000 case "guild":
2001 strs=map(users(), "PlayerRace", ME, TRUE);
2002 break;
2003 case "domain":
2004 strs=map(users(), "PlayerDomain", ME, TRUE);
2005 break;
2006 case "stat":
2007 case "stats":
2008 strs=map(users(), "PlayerStats", ME, TRUE);
2009 break;
2010 case "snoop":
2011 strs=map(users(), "PlayerSnoop", ME, TRUE);
2012 break;
2013 case "cmdavg":
2014 strs=map(users(), "PlayerCmdAvg", ME, TRUE);
2015 func="cmdavg_compare";
2016 break;
2017 default:
2018 return FALSE;
2019 }
2020 strs=sort_array(strs, func, ME);
2021 if(pipe_out&&pipe_of)
2022 write_file(pipe_of,implode(strs,"\n")+"\n");
2023 else
2024 WLN(implode(strs,"\n"));
2025 return TRUE;
2026}