blob: e80c50e63bf75824d6369373465cc5be4679141a [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001//
2// mand.c - Manpage Daemon
3//
4// Erweitert und umgearbeitet fuer die Anbindung durch
5// die Magiershell
6//
7// von Mandragon@MG
8//
9// Basiert auf der Arbeit von Hadra,Mupfel und Tyron
10// (alle @Anderland)
11//
12
13#define DEBUGGER "mandragon"
14
15#define DEBUG(x) if (find_player(DEBUGGER)) \
16 tell_object(find_player(DEBUGGER),x+"\n")
17
18
19#pragma strict_types,save_types
20#pragma no_clone,no_shadow
21
22#include <daemon/mand.h>
23
24private nosave mapping pages;
25private nosave string *keys;
26private nosave mapping pages_case;
27private nosave string *keys_case;
28
29static string glob2regexp(string str)
30{
31 str=regreplace(str,"([\\.\\^\\$\\[\\]\\(\\)])","\\\\\\1",1);
32 str=regreplace(str,"\\*",".*",1);
33 return regreplace("^"+str+"$","?",".",1);
34}
35
36void cache_entry(string entry, string dir, string file)
37{
38 string *data;
39 int j;
40
41 if (m_contains(&data,pages,lower_case(entry)))
42 {
43 j=sizeof(data);
44 while(j--) data[--j]=data[j];
45 pages[lower_case(entry)]=data+({ dir+"/"+file, dir+"/"+file});
46 }
47 else
48 {
49 pages[lower_case(entry)]=({entry,dir+"/"+file});
50 keys+=({lower_case(entry)});
51 }
52 if (m_contains(&data,pages_case,entry))
53 {
54 j=sizeof(data);
55 while(j--) data[--j]=data[j];
56 pages_case[entry]=data+({ dir+"/"+file, dir+"/"+file});
57 }
58 else
59 {
60 pages_case[entry]=({entry,dir+"/"+file});
61 keys_case+=({entry});
62 }
63 return;
64}
65
66static void load_synonyms(string dir)
67{
68 string filedata,*syn;
69
70 if (file_size(MAND_DOCDIR+dir+"/.synonym")<=0) return;
71 if (!(filedata=read_file(MAND_DOCDIR+dir+"/.synonym"))) return;
72 syn=regexplode(filedata, "([ \t][ \t]*|\n)")-({""});
73 syn-=regexp(syn,"^([ \t][ \t]*|\n)$");
74 while(sizeof(syn))
75 {
76 cache_entry(syn[0],dir,syn[1]);
77 syn=syn[2..];
78 }
79 return;
80}
81
82static void cache_directory(string dir)
83{
84 string file;
85 int i,j;
86 mixed *files;
87
88 files = get_dir(MAND_DOCDIR+dir+"/*",3)||({});
89 i=sizeof(files);
90 for (j=0;j<i;)
91 {
92 file=files[j++];
93 if (file[0]=='.')
94 {
95 j++;
96 continue;
97 }
98 if (files[j++]==-2)
99 {
100 cache_directory(dir+"/"+file);
101 continue;
102 }
103 cache_entry(file,dir,file);
104 }
105 load_synonyms(dir);
106}
107
108void update_cache()
109{
110 int i;
111 string *docdirs;
112 mixed *tmp;
113
114 tmp=get_dir(MAND_DOCDIR "*",3);
115 docdirs=({});
116 pages=([]);
117 pages_case=([]);
118 keys_case=({});
119 keys=({});
120 i=sizeof(tmp);
121 while(i--)
122 if (tmp[i]==-2)
123 docdirs+=({ tmp[(i--)-1] });
124 docdirs-=({".",".."});
125 docdirs-=MAND_EXCLUDE;
126 i=sizeof(docdirs);
127 while(i--) cache_directory(docdirs[i]);
128 return;
129}
130
131void create()
132{
133 seteuid(getuid());
134 update_cache();
135 set_next_reset(10080); //Einmal pro Woche langt
136 return;
137}
138
139void reset()
140{
141 update_cache();
142 set_next_reset(10080);
143 return;
144}
145
146//
147// locate(): Manpage im Cache suchen:
148// match = 1 -> glob-matching, match=2 -> regexp-matching
149// Pruefung ob str gueltige regexp erfolgt in der Shell
150//
151
152string *locate(string str,int match)
153{
154 string *matches,*ret,str2;
155 int i;
156
157 if (!match&&member(keys_case,str)!=-1) return pages_case[str];
158 str=lower_case(str);
159 if (match==1) str=glob2regexp(str);
160 if (match) matches=regexp(keys,str);
161 else if (member(keys,str)!=-1) matches=({ str });
162 else return ({});
163
164 ret=({});
165 i=sizeof(matches);
166 while(i--)
167 ret+=pages[matches[i]];
168 return ret;
169}