blob: f32589696fc23a3dd30e16c4553808a3269f4ac1 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// fileview.c
4//
5// $Id: fileview.c 9142 2015-02-04 22:17:29Z Zesstra $
Zesstraefad7be2018-11-06 23:18:30 +01006#pragma strict_types, rtt_checks
7#pragma range_check, pedantic
MG Mud User88f12472016-06-24 23:31:02 +02008#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +02009
10#include <ansi.h>
11#include <player/base.h>
12#include <wizlevels.h>
13#include <shells.h>
14#include <daemon/mand.h>
15#include <udp.h>
Zesstraefad7be2018-11-06 23:18:30 +010016#include <files.h>
17
MG Mud User88f12472016-06-24 23:31:02 +020018#define NEED_PROTOTYPES
19#include <magier.h>
20#include <thing/properties.h>
21#include <player.h>
22
23private nosave mapping colorstrings;
24private nosave mapping oldman_result;
25
26// ###################
27//######################### INITIALISIERUNG #############################
28// ###################
29
30mixed _query_localcmds()
31{
32 return ({({"ls","_ls",0,LEARNER_LVL}),
33 ({"more","_more",0,LEARNER_LVL}),
34 ({"cat","_cat",0,LEARNER_LVL}),
35 ({"head","_cat",0,LEARNER_LVL}),
36 ({"tail","_cat",0,LEARNER_LVL}),
37 ({"man","_man",0,LEARNER_LVL}),
38 ({"rman","_rman",0,LEARNER_LVL}),
39 ({"showprops","_showprops",0,WIZARD_LVL}),
40 ({"grep","_grep",0,LEARNER_LVL})});
41}
42
43
44// ######
45//################################ LS ###################################
46// ######
47
48//
49// _ls: Der ls-Befehl: Verzeichnisse und Dateien anzeigen
50// cmdline: Kommandozeile
51//
52
53//
54// Funktionen zum Sortieren und fuer filter_ldfied/map_ldfied
55//
56
57
58private string _get_color(string color)
59{
60 return COLORS[lower_case(color)];
61}
62
63
64private void SetColorstrings()
65{
66 string tmp,term;
67 mapping vars;
68 vars=QueryProp(P_VARIABLES);
69 colorstrings=m_allocate(0,2);
70 switch(term=QueryProp(P_TTY))
71 {
72 case "vt100":
73 case "ansi":
74 if(stringp(vars["LS_DIR"]))
75 tmp=implode(map(explode(vars["LS_DIR"],"+"),#'_get_color),
76 "");
77 else
78 tmp = (term == "ansi") ? ANSI_BLUE+ANSI_BOLD: ANSI_BOLD;
79 colorstrings[DIR] = tmp+"%s"+(term == "vt100"?"/":"")+ANSI_NORMAL;
80 if(term == "vt100") colorstrings[DIR, 1] = 1;
81 if(stringp(vars["LS_OBJ"]))
82 tmp=implode(map(explode(vars["LS_OBJ"],"+"),#'_get_color),
83 "");
84 else
85 tmp = (term == "ansi") ? ANSI_RED : ANSI_INVERS;
86 colorstrings[OBJ] = tmp+"%s"+ANSI_NORMAL;
87 if(stringp(vars["LS_VC"]))
88 tmp=implode(map(explode(vars["LS_VC"],"+"),#'_get_color),
89 "");
90 else
91 tmp = (term == "ansi") ? ANSI_PURPLE : ANSI_INVERS;
92 colorstrings[VC] = tmp+"%s"+ANSI_NORMAL;
93 break;
94 case "dumb":
95 colorstrings[DIR] = "%s/"; colorstrings[DIR, 1] = 1;
96 colorstrings[OBJ] = "%s*"; colorstrings[OBJ, 1] = 1;
97 colorstrings[VC] = "%s*"; colorstrings[VC , 1] = 1;
98 break;
99 default:
100 colorstrings[DIR] = "%s";
101 colorstrings[OBJ] = "%s";
102 colorstrings[VC] = "%s";
103 }
104 return;
105}
106
107
108private string _ls_output_short(mixed filedata,
109 int maxlen,int counter,int maxcount)
110{
111 string tmp;
112 tmp=filedata[BASENAME];
113 maxlen-=sizeof(tmp);
114 switch(filedata[FILESIZE])
115 {
Zesstraefad7be2018-11-06 23:18:30 +0100116 case FSIZE_DIR: tmp=sprintf(colorstrings[DIR],tmp);
MG Mud User88f12472016-06-24 23:31:02 +0200117 maxlen-=colorstrings[DIR,1]; break;
Zesstraefad7be2018-11-06 23:18:30 +0100118 case FSIZE_NOFILE: tmp=sprintf(colorstrings[VC],tmp);
MG Mud User88f12472016-06-24 23:31:02 +0200119 maxlen-=colorstrings[VC,1]; break;
120 default: if (find_object(filedata[FULLNAME]))
121 {
122 maxlen-=colorstrings[OBJ,1];
123 tmp=sprintf(colorstrings[OBJ],tmp); break;
124 }
125 }
126 if (!maxcount) return tmp+"\n";
127 return sprintf("%-*s%s",(maxlen+sizeof(tmp)),tmp,
Zesstraefad7be2018-11-06 23:18:30 +0100128 ((counter++)==maxcount?(counter=0,"\n"):" "));
MG Mud User88f12472016-06-24 23:31:02 +0200129}
130
131private int _ls_maxlen(mixed filedata,int flags,int maxlen)
132{
133 string base;
134 int size;
135 base=filedata[BASENAME];
136 if (!(flags&LS_A)&&(base[0]=='.')) return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200137 maxlen=max(maxlen,sizeof(base));
MG Mud User88f12472016-06-24 23:31:02 +0200138 return 1;
139}
140
141private string _ls_output_long(mixed filedata, int flags,closure valid_read,
142 closure valid_write,closure creator_file)
143{
Zesstraefad7be2018-11-06 23:18:30 +0100144 string base=filedata[BASENAME];
145 if (!(sizeof(base)) || ( (!(flags&LS_A)) && (base[0]=='.')) )
MG Mud User88f12472016-06-24 23:31:02 +0200146 return 0;
Zesstraefad7be2018-11-06 23:18:30 +0100147 int size=filedata[FILESIZE];
148 string path=filedata[PATHNAME];
Zesstraf22b6a82018-11-07 22:39:55 +0100149 string full=filedata[FULLNAME];
Zesstraefad7be2018-11-06 23:18:30 +0100150 int dir=(size==FSIZE_DIR);
151 object ob=find_object(full);
152 int ftime=filedata[FILEDATE];
153 string date;
Bugfix59cb0e52019-09-06 15:17:29 +0200154 if ((time()-ftime)>31536000) // ein Jahr
Zesstraefad7be2018-11-06 23:18:30 +0100155 date=strftime("%b %e %Y", ftime);
156 else
157 date=strftime("%b %e %H:%M", ftime);
158
159 string creator="";
160 string group="";
MG Mud User88f12472016-06-24 23:31:02 +0200161 if (flags&LS_U)
162 {
Zesstraefad7be2018-11-06 23:18:30 +0100163 creator=(string)call_other(master(),"creator_file", full);
MG Mud User88f12472016-06-24 23:31:02 +0200164 switch(creator)
165 {
166 case ROOTID: creator="root"; break;
Zesstraefad7be2018-11-06 23:18:30 +0100167 case BACKBONEID: creator="std"; break;
168 case MAILID: creator="mail"; break;
169 case NEWSID: creator="news"; break;
170 case NOBODY: creator="nobody"; break;
171 case POLIZEIID: creator="polizei"; break;
172 case DOCID: creator="doc"; break;
173 case GUILDID: creator="gilde"; break;
174 case ITEMID: creator="items"; break;
MG Mud User88f12472016-06-24 23:31:02 +0200175 default: if(!creator) creator="none"; break;
176 }
177 }
178 if (flags&LS_G)
179 {
Zesstraf22b6a82018-11-07 22:39:55 +0100180 string *tmp=explode(path, "/") - ({""});
MG Mud User88f12472016-06-24 23:31:02 +0200181 if (sizeof(tmp))
182 {
183 switch(tmp[0])
184 {
185 case WIZARDDIR: group="magier"; break;
Zesstraefad7be2018-11-06 23:18:30 +0100186 case NEWSDIR: group="news"; break;
187 case MAILDIR: group="mail"; break;
188 case FTPDIR: group="public"; break;
189 case PROJECTDIR: group="project"; break;
MG Mud User88f12472016-06-24 23:31:02 +0200190 case DOMAINDIR: if (sizeof(tmp)>1) { group=tmp[1]; break; }
191 default: group="mud"; break;
192 }
193 }
194 else group="mud";
195 }
196 if (dir) base=sprintf(colorstrings[DIR],base);
197 else
198 {
199 if (ob)
200 {
Zesstraefad7be2018-11-06 23:18:30 +0100201 if (size==FSIZE_NOFILE)
MG Mud User88f12472016-06-24 23:31:02 +0200202 base=sprintf(colorstrings[VC],base);
203 else
204 base=sprintf(colorstrings[OBJ],base);
205 }
206 }
Zesstraefad7be2018-11-06 23:18:30 +0100207 return sprintf(("%c%c%c%c %3d" + ((flags&LS_U) ? " %-24.24s" : "%-0.1s")
208 +((flags&LS_G) ? " %-8.8s" : "%0.1s") + " %8s %s %s\n"),
209 (dir ? 'd' : '-'),
MG Mud User88f12472016-06-24 23:31:02 +0200210 (!funcall(valid_read,full,getuid(),
Zesstraefad7be2018-11-06 23:18:30 +0100211 "read_file",this_object()) ? '-' : 'r'),
MG Mud User88f12472016-06-24 23:31:02 +0200212 (!funcall(valid_write,full,getuid(),
Zesstraefad7be2018-11-06 23:18:30 +0100213 "write_file",this_object()) ? '-' : 'w'),
214 (ob ? 'x' : '-'),
215 (dir ? (sizeof((get_dir(full+"/*")||({}))-({".",".."}))) : 0),
216 creator, group,
217 (dir ? "-" : size==FSIZE_NOFILE ? "<vc>" : to_string(size)),
218 date, base);
MG Mud User88f12472016-06-24 23:31:02 +0200219}
220
221
222static int _ls(string cmdline)
223{
224 int flags,cmp,i,arg_size,size;
225 int maxlen,counter,maxcount;
Arathorna8ae8662019-11-25 19:01:19 +0100226 mixed* args;
227 string output;
MG Mud User88f12472016-06-24 23:31:02 +0200228 mixed *tmp;
229 closure output_fun,v_read,v_write,creator,sort_fun;
230
231 cmdline=_unparsed_args()||"";
232 args=parseargs(cmdline,&flags,LS_OPTS,1);
233 if (flags==-1)
234 return USAGE("ls [-" LS_OPTS "] [<Verzeichnis>] [<Verzeichnis2> ..]");
235 SetColorstrings();
236 output="";
237 if (!sizeof(args)) args=({ QueryProp(P_CURRENTDIR) });
238 if (!sizeof(args=file_list(args,MODE_LSA,0,"/")))
239 return notify_fail("ls: Keine passenden Verzeichnisse gefunden.\n"), 0;
240// Files sortieren die erste
241 if (flags&LS_T) cmp=FILEDATE;
242 else if (flags&LS_S) cmp=FILESIZE;
243 else cmp=BASENAME; // =0 :-)
Arathorn06b52922018-11-26 20:47:10 +0100244
245 if ( !cmp && !(flags&LS_R) || cmp && (flags&LS_R) )
246 sort_fun = function int (mixed* a, mixed* b) {
247 return (a[cmp] > b[cmp]);
248 };
249 else
250 sort_fun = function int (mixed* a, mixed* b) {
251 return (a[cmp] < b[cmp]);
252 };
MG Mud User88f12472016-06-24 23:31:02 +0200253 args=sort_array(args,sort_fun);
254// Ausgabeformat bestimmen
255 if (flags&LS_L)
256 {
257 v_read=VALID_READ_CL;
258 v_write=VALID_WRITE_CL;
259 creator=CREATOR_CL;
260 }
261 arg_size=sizeof(args);
262 if (arg_size>1||(arg_size&&args[0][FILESIZE]>=0))
263 {
264 if (flags&LS_L)
265 tmp=map(args,#'_ls_output_long,flags,v_read,
266 v_write,creator)-({0});
267 else
268 {
269 counter=0;maxlen=0;
270 tmp=filter(args,#'_ls_maxlen,flags,&maxlen);
271 if (maxlen>76) maxlen=76;
272 maxcount=(78/(maxlen+2))-1;
273 tmp=map(tmp,#'_ls_output_short,maxlen,&counter,maxcount);
274 }
275 output=sprintf("\n%d Dateien/Unterverzeichnisse:\n%s\n",
276 sizeof(tmp),implode(tmp,""));
277 }
278 for(i=0;i<arg_size;i++)
279 {
280 tmp=({});
281 size=args[i][FILESIZE];
Zesstraefad7be2018-11-06 23:18:30 +0100282 if (size==FSIZE_DIR)
MG Mud User88f12472016-06-24 23:31:02 +0200283 {
284 tmp=file_list(({args[i][FULLNAME]+"/*"}),MODE_LSB,0,"/");
285 tmp=sort_array(tmp,sort_fun);
286 if (flags&LS_L)
287 tmp=map(tmp,#'_ls_output_long,flags,v_read,
288 v_write,creator)-({0});
289 else
290 {
291 counter=0;maxlen=0;
292 tmp=filter(tmp,#'_ls_maxlen,flags,&maxlen);
293 maxcount=(78/(maxlen+2));
294 if (maxcount) maxcount--;
295 tmp=map(tmp,#'_ls_output_short,maxlen,&counter,maxcount);
296 }
297 if (sizeof(tmp))
298 {
299 output+=sprintf("\n%s: Verzeichnis, %d Dateien/Unterverzeichnisse:\n",
300 args[i][FULLNAME],sizeof(tmp));
301 output+=(implode(tmp,"")+((string)(tmp[<1][<1..<1])=="\n"?"":"\n"));
302 }
303 else
304 {
305 output+=sprintf("\n%s: Leeres Verzeichnis.\n",args[i][FULLNAME]);
306 }
307 }
308 }
309 More(output);
310 return 1;
311}
312
313// ########
314//############################### MORE ###################################
315// ########
316//
317// _more_file: Mehrere Files hintereinander ausgeben
318//
319
320private void _more_file(string *arg)
321{
322 if (!sizeof(arg)) return;
323 printf("more: Naechste Datei: %s\n",arg[0]);
Zesstra3de3a032018-11-08 19:17:03 +0100324 More(arg[0],1,#'_more_file,
325 (sizeof(arg)>1 ? ({ arg[1..]}) : ({})) );
MG Mud User88f12472016-06-24 23:31:02 +0200326 return;
327}
328
329
330private mixed _size_filter(mixed *arg)
331{
332 if (arg[FILESIZE]>0) return arg[FULLNAME];
333 if (arg[FILESIZE]==0)
334 {
335 printf("%s: %s: Leere Datei.\n",query_verb()||"more",arg[FULLNAME]);
336 return 0;
337 }
Zesstraefad7be2018-11-06 23:18:30 +0100338 if (arg[FILESIZE]==FSIZE_DIR)
MG Mud User88f12472016-06-24 23:31:02 +0200339 printf("%s: %s ist ein Verzeichnis.\n",query_verb()||"more",arg[FULLNAME]);
340 else
341 printf("%s: %s: Datei existiert nicht.\n", query_verb()||"more",
342 arg[FULLNAME]);
343 return 0;
344}
345
346
347//
348// _more: Dateien anzeigen
349// cmdline: Kommandozeile
350//
351
352static int _more(string cmdline)
353{
354 mixed *args;
355 int flags;
356 cmdline=_unparsed_args();
357 args=parseargs(cmdline,&flags,"",1);
358 if (flags==-1||!sizeof(args)) return USAGE("more <datei> [<datei2>..]");
359 args=file_list(args,MODE_MORE,0,"/");
360 if (!sizeof(args))
361 return printf("more: %s: Keine passende Datei gefunden.\n",cmdline),1;
362 args=map(args,#'_size_filter)-({0});
363 if (sizeof(args)) _more_file(args);
364 return 1;
365}
366
367// ###################
368//########################## HEAD, TAIL, CAT #############################
369// ###################
370
371static int _cat(string cmdline)
372{
373 mixed *args;
374 int flags;
375 cmdline=_unparsed_args();
376 args=parseargs(cmdline,&flags,"",1);
377 if(flags==-1||!sizeof(args))
378 return USAGE(query_verb()+" <dateiname> [<datei2>..]");
379 args=file_list(args,MODE_CAT,0,"/");
380 if (!sizeof(args))
381 return printf("%s: %s: Keine passende Datei gefunden.\n",query_verb(),
382 cmdline),1;
383 args=map(args,#'_size_filter)-({0});
384 if (!sizeof(args)) return 1;
385 while(sizeof(args))
386 {
387 switch(query_verb())
388 {
389 case "cat":
390 if (!cat(args[0]))
391 printf("cat: %s konnte nicht angezeigt werden.\n",args[0]);
392 break;
393 case "head":
394 if (!cat(args[0],0,10))
395 printf("head: %s konnte nicht angezeigt werden.\n",args[0]);
396 break;
397 case "tail": tail(args[0]); break;
398 }
Zesstra3de3a032018-11-08 19:17:03 +0100399 if (sizeof(args) > 1)
400 args=args[1..];
401 else
402 break;
MG Mud User88f12472016-06-24 23:31:02 +0200403 }
404 return 1;
405}
406
407// #######
408//############################### MAN ###################################
409// #######
410
411static int _man(string cmdline)
412{
413 mixed *args;
414 int i, flags;
415 string *tmp, *tmp2;
416
417 cmdline=_unparsed_args();
418 args=parseargs(cmdline,&flags,MAN_OPTS,0);
419
420 if (flags==-1 ||
421 (sizeof(args)!=1 &&
422 (sizeof(args)<2 || sizeof(args[1])>1 || !(i=to_int(args[1])))))
423 return USAGE("man [-" MAN_OPTS "] <hilfeseite>");
424 tmp=explode(args[0],"/");
425
426 if (oldman_result && sizeof(tmp)==1 && sizeof(args)==1 &&
427 sizeof(tmp[0])==1 && (i=to_int(tmp[0])) && member(oldman_result,i)) {
428 tmp=({oldman_result[i,0],oldman_result[i,1]});
429 i=0;
430 }
431 else if (!(flags&(MAN_M|MAN_R))&&sizeof(tmp)>1)
432 {
433 if (file_size(MAND_DOCDIR+args[0])>=0)
434 tmp=({tmp[<1],args[0]});
435 else
436 tmp=({});
437 }
438 else
439 {
440 if (flags&MAN_R)
441 {
442 flags&=(~MAN_M);
443 if (catch(regexp(({""}),args[0]))||
444 !regexp(({""}),args[0]))
445 return printf("man: Ungueltiger Ausdruck in Maske.\n"),1;
446 }
447 tmp=(string *)call_other(MAND,"locate",args[0],flags&(MAN_M|MAN_R));
448 }
449
450 oldman_result=(mapping)0;
451 if(i && sizeof(tmp)>2 && sizeof(tmp)>=(i<<1))
452 tmp=tmp[((i<<1)-2)..((i<<1)-1)];
453 switch(sizeof(tmp))
454 {
455 case 0:
456 printf("Keine Hilfeseite gefunden fuer '%s'.\n",args[0]);
457 break;
458 case 2:
459 /*
460 if (flags&MAN_I)
461 {
462 // BRANCH TO MANUALD
463 return 1;
464 }
465 */
466 printf("Folgende Hilfeseite wurde gefunden: %s\n",tmp[1]);
467 More(MAND_DOCDIR+tmp[1],1);
468 return 1;
469 default:
470 i=sizeof(tmp)>>1;
471 tmp2=allocate(i);
472 oldman_result=m_allocate(i,2);
473 while(i)
474 {
475 tmp2[(i-1)]=sprintf("%d: ",i)+tmp[(i<<1)-2];
Zesstraefad7be2018-11-06 23:18:30 +0100476 oldman_result[i,0]=tmp[(i<<1)-2];
477 oldman_result[i,1]=tmp[(i<<1)-1];
MG Mud User88f12472016-06-24 23:31:02 +0200478 i--;
479 }
480 printf("Es wurden folgende potentiell passenden Seiten gefunden:\n"
481 "%'-'78.78s\n%s%'-'78.78s\n","",
482 break_string(implode(tmp2," "),78),"");
483 break;
484 }
485 return 1;
486}
487
488// ########
489//############################### RMAN ##################################
490// ########
491
492static int _rman(string str)
493{
494 int flags;
495 string *args;
496
497 str=_unparsed_args();
498 args=parseargs(str,&flags,"",0);
499 if (flags==-1||sizeof(args)!=2)
500 return USAGE("rman <hilfeseite> <mudname>");
501 write("man: " +
502 (string)call_other(UDP_CMD_DIR+"man","send_request",args[1],args[0]));
503 return 1;
504}
505
506
507// #############
508//############################# SHOWPROPS ###############################
509// #############
510
511//
512// _showprops: Zeigt Properties zu einem Objekt an
513//
514
515static int _showprops(string str)
516{
517 int i;
518 string *list, ausgabe;
519
520 if (str) {
521 if (str[0]!='/') str="/"+str;
522 if (str[0..4]!="/std/")
523 {
524 printf("showprops: Es koennen nur Properties von Objekten "
525 "aus /std/ angezeigt werden.\n");
526 return 1;
527 }
528 if (str[<1]=='.') str+="c";
529 if (str[<2..<1]!=".c") str+=".c";
530 if (file_size(str)<0)
531 {
532 printf("showprops: %s: Es gibt kein Objekt diesen Namens.\n",str[0..<3]);
533 return 1;
534 }
Zesstraefad7be2018-11-06 23:18:30 +0100535 if (catch(load_object(str)))
MG Mud User88f12472016-06-24 23:31:02 +0200536 {
537 printf("showprops: %s: Datei konnte nicht geladen werden.\n",str);
538 return 1;
539 }
540 }
541 if (!str || !find_object(str)) {
542 notify_fail("Welche Properties moechtest Du sehen?"
543 " Bsp.: <showprops /std/npc>\n");
544 return 0;
545 }
546 list=inherit_list(find_object(str));
MG Mud User88f12472016-06-24 23:31:02 +0200547 list=map(list,(: return $1[5..<2]+"h"; :));
548 list+=map(list,(: return explode($1,"/")[<1]; :));
549 list=map(m_indices(mkmapping(list)),(: return "/sys/"+$1; :));
550 list=filter(list,(: return file_size($1)>0; :));
MG Mud User88f12472016-06-24 23:31:02 +0200551 list=sort_array(list, #'<);
552 ausgabe="";
553 for (i=sizeof(list);i--;)
554 {
MG Mud User88f12472016-06-24 23:31:02 +0200555 str=implode(filter(explode(read_file(list[i]),"\n"),
556 (: return $1[0..9]=="#define P_";:)),"\n");
MG Mud User88f12472016-06-24 23:31:02 +0200557 if (str!="") ausgabe+=sprintf("%s\n%s\n\n", list[i], str);
558 }
559 if (ausgabe!="")
560 More(ausgabe);
561 else
562 printf("Keine Property-Definitionen zu diesem Objekt gefunden!\n");
563 return 1;
564}
565
566// ########
567//############################### GREP ###################################
568// ########
569
MG Mud User88f12472016-06-24 23:31:02 +0200570//
571// grep_file: Datei greppen
572// rexpr: Regular Expression
573// flags: Flags
574//
575
576private int grep_file(mixed filedata, string rexpr, int flags)
577{
578 string fullname,data,carry,*lines,*lines_orig,*tmp,*result;
579 int ptr,count,i,nol,match,index;
580 fullname=filedata[FULLNAME];
581 if ((flags&GREP_F)&&fullname=="/players/"+getuid()+"/grep.out")
Zesstraefad7be2018-11-06 23:18:30 +0100582 {
583 write_file("/players/"+getuid()+"/grep.out",
584 "Uebergehe grep.out ...\n");
585 return RET_FAIL;
MG Mud User88f12472016-06-24 23:31:02 +0200586 }
587 switch(filedata[FILESIZE])
588 {
Zesstraefad7be2018-11-06 23:18:30 +0100589 case FSIZE_DIR: return RET_FAIL;
590 case FSIZE_NOFILE: return ERROR(DOESNT_EXIST,fullname,RET_FAIL);
MG Mud User88f12472016-06-24 23:31:02 +0200591 case 0: return RET_FAIL;
592 default: break;
593 }
Zesstraefad7be2018-11-06 23:18:30 +0100594 if (!MAY_READ(fullname))
595 return ERROR(NO_READ,fullname,RET_FAIL);
MG Mud User88f12472016-06-24 23:31:02 +0200596 carry=""; result=({});
597 if (flags&GREP_I)
598 rexpr=lower_case(rexpr);
599 do
600 {
Arathorna78a1fc2019-11-25 22:42:26 +0100601 data=to_text(read_bytes(fullname,ptr,MAXLEN)||"", "UTF-8");
MG Mud User88f12472016-06-24 23:31:02 +0200602 ptr+=MAXLEN;
603 lines=explode(carry+data,"\n");
604 switch(sizeof(lines))
605 {
606 case 0: continue;
607 case 1:
608 carry="";
609 break;
610 default:
611 carry=lines[<1];
612 lines=lines[0..<2];
613 break;
614 }
615 lines_orig=lines;
616 if (flags&GREP_I)
617 lines=map(lines,#'lower_case);
618 nol=sizeof(lines);
619 for (i=0;i<nol;i++)
620 {
621 match=sizeof(regexp(lines[i..i],rexpr));
622 if (flags&GREP_V) match=!match;
623 if (match)
624 {
625 if (!(flags&GREP_C))
626 {
627 if (flags&GREP_N)
628 result+=({ sprintf("%4d %s",index+i+1,lines_orig[i])});
629 else
630 result+=lines_orig[i..i];
631 }
632 count++;
633 }
634 }
635 index+=nol;
636 }
637 while(sizeof(data)==MAXLEN);
638 if (carry!="")
639 {
640 if (flags&GREP_I) carry=lower_case(carry);
641 match=sizeof(regexp(({ carry }),rexpr));
642 if (flags&GREP_V) match=!match;
643 if (match)
644 {
645 if(!(flags&GREP_C))
646 {
647 if(flags&GREP_N)
648 result+=({ sprintf("%4d %s",index+1,carry) });
649 else
650 result+=({carry});
651 }
652 count++;
653 }
654 }
655 carry="";
656 if (count)
657 {
658 if (flags&GREP_L) carry=sprintf("%s\n",fullname);
659 else if (flags&GREP_H) data="";
660 else data=sprintf(" %s:",fullname);
661 if (flags&GREP_C) carry=sprintf("%s %d passende Zeile%s.\n",data,count,
662 (count==1?"":"n"));
663 else
664 carry=(data+"\n"+implode(result,"\n")+"\n");
665 }
666 if (flags&GREP_F)
667 return write_file("/players/"+getuid()+"/grep.out",carry);
668 write(carry);
669 return RET_OK;
670}
671
672static int _grep(string cmdline)
673{
674 string rexpr,mask;
675 mixed *args;
676 int flags;
677 cmdline=_unparsed_args();
678 args=parseargs(cmdline,&flags,GREP_OPTS,0);
679 if ((flags==-1)||!sizeof(args))
680 return USAGE("grep [-" GREP_OPTS
681 "] <regexp> <datei/verz> [<datei2> ... ] [<maske>]");
682 rexpr=args[0];
683 if (catch(regexp(({""}),rexpr))||!regexp(({""}),rexpr))
684 return printf("grep: Ungueltiger Suchausdruck: %s\n",rexpr) ,1;
Zesstracc3f2502018-11-14 23:46:47 +0100685 args=(sizeof(args)>1 ? args[1..] : ({}) );
MG Mud User88f12472016-06-24 23:31:02 +0200686 if (flags&GREP_M)
687 {
688 mask=args[<1];
Zesstracc3f2502018-11-14 23:46:47 +0100689 if (sizeof(args) > 2)
690 args = (sizeof(args) > 1 ? args[0..<2] : ({}) );
MG Mud User88f12472016-06-24 23:31:02 +0200691 }
692 if (!sizeof(args))
693 return USAGE("grep [-" GREP_OPTS
694 "] <regexp> <datei/verz> [<datei2> ... ] [<maske>]");
695 args=map(args,#'to_filename)-({0});
MG Mud User88f12472016-06-24 23:31:02 +0200696 args=file_list(args,MODE_GREP,(flags&GREP_R?1:0),"/",mask);
697 if (!sizeof(args))
698 return printf("Keine passenden Dateien gefunden.\n"),1;
699 if (flags&GREP_I) rexpr=lower_case(rexpr);
700 if (flags&GREP_F)
701 {
Zesstraefad7be2018-11-06 23:18:30 +0100702 if (file_size("/players/"+getuid()+"/grep.out")==FSIZE_DIR
703 || !MAY_WRITE("/players/"+getuid()+"/grep.out"))
MG Mud User88f12472016-06-24 23:31:02 +0200704 return printf("grep: Datei /players/%s/grep.out kann nicht "
Zesstraefad7be2018-11-06 23:18:30 +0100705 "geschrieben werden.\n",getuid()),1;
MG Mud User88f12472016-06-24 23:31:02 +0200706 else
707 write_file("/players/"+getuid()+"/grep.out",
708 "Ausgabe von \"grep " + _unparsed_args() + "\":\n");
709 }
710 asynchron(args,#'grep_file,rexpr,flags,0);
711 return 1;
712}