master.h-Dateireferenz

#include "/secure/config.h"
#include "/sys/userinfo.h"
#include "/sys/shells.h"
#include "/sys/player/base.h"
#include "/sys/moving.h"
#include "/sys/defines.h"
#include "/sys/wizlist.h"
#include "/sys/daemon.h"
#include "/sys/mail.h"
#include "/sys/driver_hook.h"
#include "/sys/functionlist.h"
#include "/secure/wizlevels.h"
Include-Abhängigkeitsdiagramm für master.h:
Dieser Graph zeigt, welche Datei direkt oder indirekt diese Datei enthält:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define P_WEAPON   "weapon"
#define P_DEFAULT_NOTIFY_FAIL   "default_notify_fail"
#define DEBUG_MSG(x, po)
#define DEBUG2_MSG(x, po)
#define DEBUG3_MSG(x)
#define DEBUG4_MSG(x, po)
#define DEBUG(x)
#define READ_FILE   "/log/ARCH/READ_FILE"
#define CRASH_LOG   "/log/CRASH_LOG"
#define MAX_ERRLOG_SIZE   51200
#define log_file(file, str)   write_file("/log/"+file, str)
#define NAME(x)   getuid(x)
#define CAP_NAME(x)   capitalize(NAME(x))
#define TP   efun::this_player()
#define TI   efun::this_interactive()
#define PO   efun::previous_object()
#define TO   efun::this_object()
#define WIZ_HELP_MAIL_DIR   "/doc/infomails/"

Funktionen

string creator_file (mixed str)
mixed give_uid_to_object (string datei, object po)
void save_wiz_file ()
mixed load_uid_hook (string datei)
mixed clone_uid_hook (string blueprint, string new_name)
int domain_master (string user, string domain)
int domain_member (string user, string domain)
string * get_domain_homes (string wiz)
void LoadDeputyFileList ()
mixed valid_read (string path, string euid, string fun, object obj)
mixed valid_write (string path, string euid, string fun, object obj)
string _get_path (string path, string user)
mixed QueryBanished (string str)
int TBanishName (string name, int days)
protected void SendWizardHelpMail (string name, int level)
public int find_userinfo (string user)
protected mixed * get_full_userinfo (string user)
public mixed * get_userinfo (string user)
public int get_wiz_level (string user)
public string query_player_object (string name)
public int query_wiz_level (mixed player)
int update_wiz_level (string user, int lev)
protected void set_guilds (string player, string *guilds)
protected void set_domains (string player, string *domains)
void update_late_players ()
public string secure_savefile (string name)
protected void save_userinfo (string user)
protected string query_secure_euid ()
protected int query_secure_level ()
private string * ExpandUIDAlias (string alias, int rec)
public varargs string * QueryUIDAlias (string alias, int rec)
public string * AddWizardForUID (string uid, string wizuid)
public string * RemoveWizardFromUID (string uid, string wizuid)
public varargs string * QueryWizardsForUID (string uid, int recursive)
public varargs string * QueryUIDsForWizard (string wizuid, int recursive)

Makro-Dokumentation

#define CAP_NAME ( x   )     capitalize(NAME(x))

Definiert in Zeile 73 der Datei master.h.

#define CRASH_LOG   "/log/CRASH_LOG"

Definiert in Zeile 65 der Datei master.h.

#define DEBUG ( x   ) 
Wert:
if (funcall(symbol_function('find_player),"zesstra"))\        tell_object(funcall(symbol_function('find_player),"zesstra"),\
        "MDBG: "+x+"\n")

Definiert in Zeile 56 der Datei master.h.

#define DEBUG2_MSG ( x,
po   ) 
Wert:
catch(CHMASTER->send("Entwicklung", \
                capitalize(objectp(po) ? REAL_UID(po) : ""), x))

Definiert in Zeile 45 der Datei master.h.

Wird benutzt von handle_runtime_error() und renew_player_object().

#define DEBUG3_MSG ( x   ) 
Wert:
catch(CHMASTER->send("Entwicklung", \
                "<MasteR>", x))

Definiert in Zeile 47 der Datei master.h.

#define DEBUG4_MSG ( x,
po   ) 
Wert:
catch(CHMASTER->send("Warnungen", \
                capitalize(objectp(po) ? REAL_UID(po) : ""), x))

Definiert in Zeile 50 der Datei master.h.

#define DEBUG_MSG ( x,
po   ) 
Wert:
catch(CHMASTER->send("Debug", \
                capitalize(objectp(po) ? REAL_UID(po) : ""), x))

Definiert in Zeile 43 der Datei master.h.

Wird benutzt von handle_runtime_error() und renew_player_object().

#define log_file ( file,
str   )     write_file("/log/"+file, str)
#define MAX_ERRLOG_SIZE   51200

Definiert in Zeile 69 der Datei master.h.

#define NAME ( x   )     getuid(x)

Definiert in Zeile 72 der Datei master.h.

#define P_DEFAULT_NOTIFY_FAIL   "default_notify_fail"

Definiert in Zeile 23 der Datei master.h.

#define P_WEAPON   "weapon"
#define PO   efun::previous_object()

Definiert in Zeile 76 der Datei master.h.

#define READ_FILE   "/log/ARCH/READ_FILE"

Definiert in Zeile 62 der Datei master.h.

Wird benutzt von valid_read().

#define TI   efun::this_interactive()

Definiert in Zeile 75 der Datei master.h.

#define TO   efun::this_object()
#define TP   efun::this_player()

Definiert in Zeile 74 der Datei master.h.

#define WIZ_HELP_MAIL_DIR   "/doc/infomails/"

Definiert in Zeile 80 der Datei master.h.


Dokumentation der Funktionen

string _get_path ( string  path,
string  user 
)

Definiert in Zeile 77 der Datei file_access.c.

Benutzt full_path_array().

Wird benutzt von AddPotionroom(), AddQuest(), ChangeMiniQuest(), ChangeRoomPath(), get_edit_line(), goto(), make_path_absolute() und set_player_object().

00077                                            {
00078   string *p_arr = full_path_array(path, user);
00079   // make path absolute
00080   if (p_arr[0] != "")
00081       p_arr = ({""}) + p_arr;
00082 
00083   return implode(p_arr,"/");
00084 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public string* AddWizardForUID ( string  uid,
string  wizuid 
)

Definiert in Zeile 209 der Datei userinfo.c.

00209                                                           {
00210     if (!stringp(wizuid) || !strlen(wizuid)
00211         || !IS_LEARNER(wizuid))
00212         return(({}));
00213 
00214     //Zugriff nur als EM oder jemand, der fuer die UID zustaendig ist.
00215     if ( funcall(symbol_function('secure_level)) < ARCH_LVL 
00216         && member(
00217             QueryUIDsForWizard(funcall(symbol_function('secure_euid))),
00218             uid) == -1)
00219         return(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]);
00220 
00221     if (!pointerp(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]))
00222         //Array neu anlegen
00223         userlist[wizuid,USER_UIDS_TO_TAKE_CARE]=({uid});
00224     else {
00225         //Ein Array schon vorhanden
00226         if (member(userlist[wizuid,USER_UIDS_TO_TAKE_CARE],uid)==-1)
00227             //uid nicht drin
00228             userlist[wizuid,USER_UIDS_TO_TAKE_CARE]=
00229               userlist[wizuid,USER_UIDS_TO_TAKE_CARE]+({uid});
00230     }
00231     save_userinfo(wizuid);
00232     // aus dem UID-Alias-Cache werfen
00233     efun::m_delete(uidaliase, wizuid);
00234     // Aufruf, um userids und uidaliase zu aktualisieren
00235     QueryUIDsForWizard(wizuid);
00236     return(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]);
00237 }

mixed clone_uid_hook ( string  blueprint,
string  new_name 
)

Definiert in Zeile 1116 der Datei master.c.

Benutzt give_uid_to_object().

01116                                                                  {
01117     return(give_uid_to_object(new_name,previous_object()));
01118 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

string creator_file ( mixed  str  ) 

Definiert in Zeile 362 der Datei master.c.

Wird benutzt von call_out_info(), compile_object(), get_wiz_name(), preload() und valid_write().

00362                                {
00363   string *strs,tmp;
00364   int s;
00365 
00366   // full_path_array nach strs
00367   // TODO: was ist mit clones?
00368   if(objectp(str))
00369     strs=full_path_array(object_name(str), 0);
00370   else if(stringp(str))
00371     strs=full_path_array(str, 0);
00372   else return NOBODY;
00373 
00374   // absolute Pfade interessieren hier gerade nicht.
00375   strs -= ({""});
00376 
00377   s=sizeof(strs);
00378   if(s<2) return NOBODY;
00379 
00380   switch(strs[0]) {
00381     case DOMAINDIR:
00382       // Fuer Nicht-Magier bzw. "Pseudo-"Magier die Regionskennung
00383       if( s==2 || WIZLVLS[strs[2]] || !IS_LEARNER(strs[2]) )
00384         return strs[1];
00385 
00386       // in /d/erzmagier gibt es Magier-IDs
00387       if (strs[1]=="erzmagier") return strs[2];
00388 
00389       // Ansonsten d.region.magiername
00390       return sprintf("d.%s.%s", strs[1], strs[2]);
00391  
00392     case PROJECTDIR:
00393       // In p.service gibt es ids mit uid
00394       if (s>2 && strs[1]=="service") return "p.service."+strs[2];
00395 
00396       // Ansonsten nur p.projekt (p.service ist auch hier drin)
00397       return "p."+strs[1];
00398 
00399     case WIZARDDIR:
00400       if (s>2)
00401         return strs[1];
00402       if (s==2 && file_size(strs[0]+"/"+strs[1])==FSIZE_DIR)
00403         return strs[1];
00404       return NOBODY;
00405 
00406     case SECUREDIR:
00407       return ROOTID;
00408 
00409     case GUILDDIR:
00410     case SPELLBOOKDIR:
00411       tmp=strs[1];
00412       if (tmp[<2..<2]==".") tmp=tmp[0..<3];
00413       if ((s=member(tmp,'.'))>0) tmp=tmp[s+1..];
00414       return "GUILD."+tmp;
00415 
00416     case LIBROOMDIR:
00417       return ROOMID;
00418 
00419     case STDDIR:
00420     case LIBOBJDIR:
00421       return BACKBONEID;
00422 
00423     case DOCDIR:
00424       return DOCID;
00425 
00426     case MAILDIR:
00427       return MAILID;
00428     case NEWSDIR:
00429       return NEWSID;
00430 
00431     /* Fall-Through */
00432     default:
00433       return NOBODY;
00434 
00435  }
00436  return(NOBODY);  //should never be reached.
00437 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

int domain_master ( string  user,
string  domain 
)

Definiert in Zeile 12 der Datei domain.c.

Benutzt domains, find_userinfo(), get_userinfo(), i und USER_DOMAIN.

Wird benutzt von ShowEPObjects(), valid_read() und valid_write().

00013 {
00014   string *domains;
00015   int i;
00016   
00017   if (!find_userinfo(user)||
00018       !pointerp(domains=get_userinfo(user)[USER_DOMAIN+1]))
00019     return 0;
00020   return (member(domains,domain) != -1);
00021 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

int domain_member ( string  user,
string  domain 
)

Definiert in Zeile 23 der Datei domain.c.

Benutzt IS_DOMAINMEMBER.

Wird benutzt von valid_write().

00024 {
00025   if (domain=="erzmagier") return 0;
00026   return (IS_DOMAINMEMBER(user)&&file_size("/d/"+domain+"/"+user)==-2);
00027 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

private string* ExpandUIDAlias ( string  alias,
int  rec 
)

Definiert in Zeile 946 der Datei userinfo.c.

Benutzt __MAX_MAPPING_KEYS__, DOMAINDIR, find_userinfo(), FSIZE_DIR, guild, GUILDDIR, GUILDID, GUILDMASTER, P_GUILD_DEFAULT_SPELLBOOK, PROJECTDIR, QueryUIDsForWizard(), uidaliase und uids.

00946                                                       {
00947   
00948   string *uids=({});
00949 
00950   // Regionsname?
00951   if (file_size("/"DOMAINDIR"/"+alias) == FSIZE_DIR) {
00952     //generelle Pseudo-UID 'd.region' und 'region' fuer geloeschte
00953     //Magier dieser Region
00954     uids += ({DOMAINDIR"."+alias, alias});
00955     //alle Magier-Verzeichnisse ermitteln:
00956     string tmpdir="/"DOMAINDIR"/"+alias+"/";
00957     foreach(string dir: (get_dir(tmpdir+"*") || ({}))
00958                           - ({".","..",".svn"})) {
00959       // schauen, obs nen (sichtbares) Verzeichnis ist und ob der Magier
00960       // existiert. Letzteres aber nur, falls die Rekursionstiefe min. 100
00961       // ist, da beim Nachschauen eines Magiers mit (mehreren)
00962       // RM-Posten, der in der Region RMs aus anderen Regionen hat, leicht
00963       // Rekursionstiefen von 20 (*4) auftreten koennen, wenn noch gar
00964       // keine UIDs im Cache sind (find_userinfo() ruft indirekt diese
00965       // Funktion).
00966       if (dir[0]!='.' 
00967           && file_size(tmpdir+dir) == FSIZE_DIR
00968 #if __MAX_RECURSION__ > 99
00969           && find_userinfo(dir)
00970 #endif
00971           )
00972           uids += ({DOMAINDIR"."+alias+"."+dir});
00973     }
00974   }
00975   // Gildenname?
00976   else if (GUILDMASTER->ValidGuild(alias)) {
00977       uids += ({GUILDID"."+alias});
00978       //hat die Gilde ein Projektverzeichnis?
00979       if (file_size("/"PROJECTDIR"/"+alias) == FSIZE_DIR) {
00980           uids += ({PROJECTDIR"."+alias});
00981       }
00982       // jetzt haben dummerweise die Spellbooks meist nicht den gleichen
00983       // Namen wie die Gilde. D.h. die Gilde muss nun noch nach dem
00984       // Namen des Spellbooks gefragt werden, weil dessen UID nicht
00985       // unbedingt gleich dem der Gilde ist. *seufz*
00986       string spbook;
00987       object guild;
00988       catch(guild=load_object(GUILDDIR"/"+alias));
00989       if (objectp(guild) 
00990           && (strlen(spbook=(string)
00991                  guild->QueryProp(P_GUILD_DEFAULT_SPELLBOOK)))
00992                 && spbook!=alias)
00993           uids += ({GUILDID"."+spbook});
00994   }
00995   // Spieler/Magier-UID?
00996   else if (find_userinfo(alias)) {
00997     // wenn rec > 0, wird eine Spieler-UID als Alias aufgefasst und zu seinen
00998     // UIDs expandiert. Hierbei erfolgt aber nur eine Rekursion.
00999     if (!rec) uids = QueryUIDsForWizard(alias, 1);
01000     else uids = ({alias});
01001   }
01002   // Projektkrams? -> alle Subdirs von /p/ ausser /p/service selber.
01003   else if (alias==PROJECTDIR) {
01004     foreach(string dir: (get_dir("/"PROJECTDIR"/*") || ({}))
01005                          - ({".","..",".svn","service"})) {
01006       if (dir[0]!='.' &&
01007           file_size("/"PROJECTDIR"/"+dir) == FSIZE_DIR)
01008           uids += ({PROJECTDIR"."+dir});
01009     }
01010   }
01011   // p.service? -> Alle Subdirs von /p/service.
01012   else if (alias==PROJECTDIR".service") {
01013     foreach(string dir: (get_dir("/"PROJECTDIR"/service/*") || ({}))
01014                          - ({".","..",".svn"})) {
01015       if (dir[0]!='.' &&
01016           file_size("/"PROJECTDIR"/service/"+dir) == FSIZE_DIR)
01017           uids += ({PROJECTDIR".service."+dir});
01018     }
01019   }
01020   // wenn nix zutrifft -> unexpandiert zurueckgeben
01021   else
01022     uids = ({alias});
01023 
01024   // im Cache vermerken
01025   if (sizeof(uidaliase) >= __MAX_MAPPING_KEYS__)
01026       uidaliase=m_allocate(1);
01027   // auch vermerken, wenn keine UIDs ermittelt wurden.
01028   uidaliase += ([alias: uids]);
01029   return uids;
01030 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

public int find_userinfo ( string  user  ) 

Definiert in Zeile 346 der Datei userinfo.c.

Benutzt __MAX_MAPPING_KEYS__, __MAX_MAPPING_SIZE__, creation_date, domains, ek, ektips, ep, file(), fptips, guilds, i, LEARNER_LVL, level, mq, password, QueryUIDsForWizard(), restore_object(), secure_savefile(), shell, uidstotakecare, USER_LEVEL, USER_TOUCH und userlist.

Wird benutzt von add_domain_master(), add_guild_master(), advance_wizlevel(), delete_player(), domain_master(), ExpandUIDAlias(), get_userinfo(), get_wiz_level(), guild_master(), query_ek(), query_ektips(), query_ep(), query_fptips(), query_mq(), query_player_object(), QueryWizardsForUID(), remove_domain_master(), remove_guild_master(), set_player_object(), update_ek(), update_ektips(), update_ep(), update_fptips(), update_mq(), update_password() und update_wiz_level().

00346                                       {
00347   string file;
00348   int i;
00349   if (!stringp(user) || !strlen(user) 
00350       || member(user,' ')!=-1 || member(user,':')!=-1)
00351     return 0;
00352   if (!member(userlist,user)) {
00353       //erstmal schauen, ob wir mit einem neuen Eintrag nicht die max.
00354       //Mapping-Groessen ueberschreiten, wenn ja, einen Eintrag loeschen
00355       //BTW: widthof()+1 ist richtig so.
00356       //BTW2: Ich hoffe, die max. Arraygroesse ist immer gross genug, sollte 
00357       //sie aber sein bei ner Mappingbreite von 10.
00358       // BTW3: Dieses Rausloeschen von einem Eintrag bei Erreichen der Grenze
00359       // erhoeht die benoetigten Ticks fuer diese Funktion um das 5-6fache und
00360       // die noetige Zeit um das 70fache. Daher wird der Cache bei Erreichen
00361       // der Grenze jetzt einfach geloescht.
00362       if ( ( (i=sizeof(userlist)+1) >= __MAX_MAPPING_KEYS__) 
00363           || (( i * (widthof(userlist)+1)) >
00364                  __MAX_MAPPING_SIZE__))    
00365           //efun::m_delete(userlist,m_indices(userlist)[0]);
00366           userlist=m_allocate(1,widthof(userlist));
00367 
00368       // Usersavefile finden
00369       if ((file=secure_savefile(user))=="") {
00370         // User gibt es nicht, aber Anfrage cachen
00371           userlist+=([user: "NP"; -1; ({}); "LOCKED"; -1; time(); ""; ""; "";
00372           ({});"";""; 0 ]);
00373           return 0;
00374       }
00375       password="";
00376       ep="";
00377       ek="";
00378       mq="";
00379       guilds=({});
00380       ektips="";
00381       fptips="";
00382       uidstotakecare=0;
00383       if (!restore_object(file)) return 0;
00384       userlist+=([user: password; level; domains; shell; creation_date; 
00385           time();ep; ek; mq; guilds; ektips; fptips; uidstotakecare]);
00386       // die speziellen UIDs, fuer die dieser Magier zustaendig ist, ermitten
00387       // und gleichzeitig im entsprechenden Mapping fuers Reverse-Loopup
00388       // speichern.
00389       if (level >= LEARNER_LVL)
00390         QueryUIDsForWizard(user);
00391   }
00392   userlist[user,USER_TOUCH]=time();
00393   if (userlist[user,USER_LEVEL]==-1) return 0;
00394   return 1;
00395 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

string* get_domain_homes ( string  wiz  ) 

Definiert in Zeile 80 der Datei domain.c.

Benutzt FSIZE_DIR, get_domains(), query_wiz_level() und WIZARD_LVL.

Wird benutzt von create_wizard() und stat().

00081 {
00082   string *homes=({});
00083   string tmp;
00084   
00085   if (query_wiz_level(wiz)<=WIZARD_LVL) return ({});
00086 
00087   tmp = "/d/%s/"+wiz;
00088   foreach(string dir: get_domains()) {
00089       if (dir[0]!='.' && file_size(sprintf(tmp,dir)) == FSIZE_DIR)
00090           //Magierverzeichnis da und faengt nicht mit "." an: aufnehmen.
00091           homes+=({dir});
00092   }
00093   return homes;
00094 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected mixed* get_full_userinfo ( string  user  ) 

Definiert in Zeile 835 der Datei userinfo.c.

Wird benutzt von advance_wizlevel() und CheckPasswd().

00835                                                 {
00836   if(!user||user=="")
00837     return 0;
00838   user=explode(user,".")[0];
00839   if (!member(userlist,user) && !find_userinfo(user))
00840     return 0;
00841 
00842   return({user,userlist[user,USER_PASSWORD],userlist[user,USER_LEVEL],
00843       userlist[user,USER_DOMAIN], userlist[user,USER_OBJECT],
00844       userlist[user,USER_CREATION_DATE], 0, 0, userlist[user,USER_GUILD],
00845       userlist[user,USER_EKTIPS],userlist[user,USER_FPTIPS],
00846       userlist[user,USER_UIDS_TO_TAKE_CARE]});
00847 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public mixed* get_userinfo ( string  user  ) 

Definiert in Zeile 398 der Datei userinfo.c.

Benutzt find_userinfo(), USER_CREATION_DATE, USER_DOMAIN, USER_EKTIPS, USER_FPTIPS, USER_GUILD, USER_LEVEL, USER_OBJECT, USER_UIDS_TO_TAKE_CARE und userlist.

Wird benutzt von add_domain_master(), add_guild_master(), domain_master(), guild_master(), remove_domain_master(), remove_guild_master() und Validate().

00398                                         {
00399   if(!user||user=="")
00400     return 0;
00401   user=explode(user,".")[0];
00402   if (!member(userlist,user) && !find_userinfo(user))
00403     return 0;
00404 
00405   if (userlist[user,USER_LEVEL]==-1) return 0;
00406 
00407   return({user,"##"+user,userlist[user,USER_LEVEL],
00408       userlist[user,USER_DOMAIN], userlist[user,USER_OBJECT],
00409       userlist[user,USER_CREATION_DATE], 0, 0,
00410       userlist[user,USER_GUILD],
00411       userlist[user,USER_EKTIPS],userlist[user,USER_FPTIPS],
00412       userlist[user,USER_UIDS_TO_TAKE_CARE]});
00413 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public int get_wiz_level ( string  user  ) 

Definiert in Zeile 491 der Datei userinfo.c.

Benutzt find_userinfo(), USER_LEVEL und userlist.

Wird benutzt von add_domain_master(), delete_player(), FtpAccess(), query_wiz_level() und valid_write().

00491                                       {
00492   if (user && find_userinfo(user)) 
00493     return userlist[user,USER_LEVEL];
00494   //return 0 if no user given (return type needed)
00495   return(0);
00496 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mixed give_uid_to_object ( string  datei,
object  po 
)

Definiert in Zeile 441 der Datei master.c.

Wird benutzt von clone_uid_hook().

00442 {
00443   string creator,pouid;
00444 
00445   // Parameter testen
00446   if (!stringp(datei)||!objectp(po))  return 1;
00447 
00448   // Datei muss Besitzer haben
00449   if (!(creator=creator_file(datei))) return 1;
00450   
00451   // Keine Objekte in /log und /open
00452   if (datei[0..2]=="log" || datei[0..3]=="open") return 1;
00453 
00454   // Hack, damit simul_efun geladen werden kann
00455   if (creator==ROOTID && po==TO) return ROOTID;
00456 
00457   // Keine euid, kein Laden ...
00458   if (!(pouid=geteuid(po))) return 1; // Disallow if no euid in po
00459 
00460   // Root generiert keine Root-Objekte ;-)
00461   // Nur UID setzen
00462   if (pouid==ROOTID)
00463     return ({creator,NOBODY}); // root does not create root objects!
00464 
00465   // EUID mitsetzen, wenn PO==creator oder creator==BACKBONEID
00466   if (creator==pouid || creator==BACKBONEID)
00467     return pouid;
00468 
00469   return ({creator,NOBODY});
00470 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mixed load_uid_hook ( string  datei  ) 

Definiert in Zeile 1108 der Datei master.c.

Wird benutzt von inaugurate_master().

01108                                             {
01109     return(give_uid_to_object(datei,previous_object()));
01110 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void LoadDeputyFileList (  ) 

Definiert in Zeile 16 der Datei file_access.c.

Benutzt deputy_files.

Wird benutzt von CheckDeputyRights().

00017 {
00018   // Leseberechtigungen fuer /log/ARCH/* setzen
00019   deputy_files = efun::explode( read_file("/log/ARCH/DEPUTY_FILELIST") || "",
00020                                 "\n" ) - ({""});
00021   return;
00022 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public string query_player_object ( string  name  ) 

Definiert in Zeile 416 der Datei userinfo.c.

Benutzt find_userinfo(), USER_OBJECT, userentry und userlist.

Wird benutzt von renew_player_object().

00417 {
00418   mixed *userentry;
00419   if( !find_userinfo(name) ) return "";
00420   return userlist[name,USER_OBJECT];
00421 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected string query_secure_euid (  ) 
protected int query_secure_level (  ) 
public int query_wiz_level ( mixed  player  ) 

Definiert in Zeile 499 der Datei userinfo.c.

Benutzt DOMAINDIR, get_wiz_level(), GUILDID, PROJECTDIR und WIZLVLS.

Wird benutzt von __auswerten(), _query_info(), _set_earmuffs(), actions(), allowed(), befoerdere(), call_out_info(), check(), check_arch(), command_me(), CommandScan(), create_wizard(), do_mail(), finger_single(), format_paths(), get_domain_homes(), HitFunc(), is_greater(), is_wiz_level_ge(), is_wiz_level_lt(), logaccess(), Message(), scan(), search_for_path(), secure(), security(), set_max_guests(), sponsoring(), stat(), valid_read(), valid_write() und WizLevel().

00500 {
00501     if ( objectp(player) && query_once_interactive(player) )
00502         return get_wiz_level( getuid(player) );
00503     else {
00504         // erstmal UID ermitteln, falls Objekt
00505         //if (objectp(player))
00506         //    player=getuid(player);
00507         if ( stringp(player) ) {
00508             if( player[0..1]==DOMAINDIR"." ) return 25;
00509             if( player[0..5]==GUILDID"." ) 
00510                 return WIZLVLS[GUILDID];
00511             if( player[0..1]==PROJECTDIR"." ) return 21;
00512             // die alte Loesung mit || verhaelt sich falsch, wenn ein UID ne
00513             // spezielle ist, der Level 0 zugeordnet wurde und es einen
00514             // Spieler mit diesem namen gibt.
00515             if (member(WIZLVLS,player)) 
00516                 return(WIZLVLS[player]);
00517             return get_wiz_level(player);
00518         }
00519     }
00520     return 0;
00521 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mixed QueryBanished ( string  str  ) 

Definiert in Zeile 37 der Datei misc.c.

Benutzt banished und i.

Wird benutzt von BanishName(), finger_single(), good_password() und logon2().

00037                                {
00038   int i;
00039 
00040   if (!str) return 0;
00041   if (!pointerp(banished)) return 0;
00042   for (i=sizeof(banished)-1;i>=0;i--)
00043     if (sizeof(regexp(({str}),"^"+banished[i][0]+"$")))
00044     {
00045       if (!banished[i][1] || banished[i][1]=="")
00046         return "Dieser Name ist gesperrt.";
00047       else
00048         return banished[i][1];
00049     }
00050   return 0;
00051 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public varargs string* QueryUIDAlias ( string  alias,
int  rec 
)

Definiert in Zeile 105 der Datei userinfo.c.

00105                                                             {
00106   string *uids;
00107   if (!stringp(alias) || !strlen(alias))
00108       return ({});
00109   // Wen im cache, gehts schnell.
00110   if (member(uidaliase, alias))
00111       uids = uidaliase[alias];
00112   else
00113       uids = ExpandUIDAlias(alias, rec);
00114 
00115   if (extern_call())
00116     return copy(uids);
00117   
00118   return(uids);
00119 }

public varargs string* QueryUIDsForWizard ( string  wizuid,
int  recursive 
)

Definiert in Zeile 126 der Datei userinfo.c.

Wird benutzt von access_check(), ExpandUIDAlias() und find_userinfo().

00126                                                                         {
00127     string *uids, *tmp, *uidstoadd;
00128     int i;
00129 
00130     if (!stringp(wizuid) || !strlen(wizuid) || !IS_LEARNER(wizuid))
00131         return(({}));
00132 
00133     if (!find_userinfo(wizuid))
00134         return(({}));
00135 
00136     uidstoadd=({}); //diese werden hinterher in userids gespeichert.
00137 
00138     // als erstes die ratebaren UIDs. ;-)
00139     uids=({wizuid});
00140     // Regionen ermitteln, wo wizuid ein Verzeichnis hat und entsprechende
00141     // UIDs anhaengen:
00142     foreach(string region: get_domain_homes(wizuid)) {
00143         uids+=({ sprintf(DOMAINDIR".%s.%s",region,wizuid) });
00144     }
00145     // Verzeichnis in /p/service?
00146     if (file_size(PROJECTDIR"/service/"+wizuid) == FSIZE_DIR)
00147         uids+=({PROJECTDIR".service."+wizuid});
00148 
00149     // Gildenchef?
00150     if (pointerp(userlist[wizuid,USER_GUILD])) {
00151         foreach(string gilde: userlist[wizuid,USER_GUILD]) {
00152           uidstoadd += QueryUIDAlias(gilde);
00153         }
00154     }
00155     // Regionsmagier?
00156     if (pointerp(userlist[wizuid,USER_DOMAIN])) {
00157         foreach(string domain: userlist[wizuid,USER_DOMAIN]) {
00158             //generelle Pseudo-UID 'd.region' und 'region' fuer geloeschte
00159             //Magier dieser Region vormerken, um sie hinterher fuers
00160             //Reverse-Lookup ins uid-Mapping zu schreiben.
00161             string *pseudo=({DOMAINDIR"."+domain, domain});
00162             uidstoadd += pseudo;
00163             // Rest macht QueryUIDAlias, dabei aber die von der Funktion
00164             // ebenfalls gelieferten Pseudo-UIDs wieder abziehen.
00165             uids += QueryUIDAlias(domain) - pseudo;
00166         }
00167     }
00168     // jetzt noch nachgucken, fuer welche UIDs dieser Magier explizit noch
00169     // zustaendig ist.
00170     if (pointerp(userlist[wizuid,USER_UIDS_TO_TAKE_CARE])) {
00171     // dies koennte etwas a la "region" oder "anderermagier" sein, d.h. dieser
00172     // Magier ist fuer alle UIDs von 'andermagier' auch zustaendig. Daher muss
00173     // jedes davon durch QueryUIDAlias() (was im Falle von Spielern wiederum
00174     // QueryUIDsForWizard() ruft, aber die Rekursion im Falle von Spielern ist
00175     // auf 1 begrenzt).
00176         foreach(string uid2: userlist[wizuid,USER_UIDS_TO_TAKE_CARE]) {        
00177             uidstoadd += QueryUIDAlias(uid2, recursive);
00178         }
00179     }
00180 
00181     // so, in uidstoadd stehen UIDs drin, die nicht Magiername selber,
00182     // d.region.magier oder p.service.magier sind und bei welchen folglich das
00183     // Mapping UIDs-nach-Magier nur mit einer Liste moeglich ist. In die
00184     // werden die uids nun eingetragen. (z.B. d.region)
00185     if (sizeof(uidstoadd)) {
00186         // genug Platz in userids? Sonst welche rauswerfen. :-/ 
00187         // (besser als bug) TODO: Auf 10k begrenzen -> max Arraygroesse!
00188         if ( sizeof(userids)+(i=sizeof(uidstoadd))               
00189             >= __MAX_MAPPING_KEYS__) {
00190             foreach(string tmpuid: m_indices(userids)[0..i])        
00191               efun::m_delete(userids,tmpuid);  
00192         }
00193         foreach(string tmpuid: uidstoadd) {  
00194             if (member(userids,tmpuid)) {  
00195                 //User dem Array hinzufuegen, wenn noch nicht drin.
00196                 if (member(userids[tmpuid],wizuid)==-1)
00197                     userids[tmpuid]=userids[tmpuid]+({wizuid});              
00198             }
00199             //sonst neuen Eintragen hinzufuegen            
00200             else
00201                 m_add(userids,tmpuid,({wizuid}));          
00202         }
00203     } // Ende spez. uids speichern
00204     
00205     return(uids+uidstoadd);
00206 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public varargs string* QueryWizardsForUID ( string  uid,
int  recursive 
)

Definiert in Zeile 34 der Datei userinfo.c.

Benutzt find_userinfo(), QueryWizardsForUID() und userids.

Wird benutzt von QueryWizardsForUID().

00034                                                                      {
00035 
00036     if (!stringp(uid) || !strlen(uid))
00037         return(({}));
00038 
00039     string *tolookup=({uid}); //diese spaeter in userids nachgucken.
00040     string *wizards=({});
00041     // Schauen, was automatisch ermittelt werden kann.
00042     string *parts=explode(uid,".");
00043     switch(sizeof(parts)) {
00044          case 3:
00045           // z.B. d.region.magier und p.service.magier
00046           if (find_userinfo(parts[2]))
00047               //Magier existiert, reinschreiben.
00048               wizards+=({parts[2]});
00049           if (parts[0]=="d")
00050               // d.region noch nachgucken (RMs)
00051               tolookup=({implode(parts[0..1],".")});
00052           break;
00053         //case 2:
00054           // GUILD.gilde, p.project, d.region
00055           // koennen nur in userids nachgeguckt werden (s.u. tolookup)
00056           // muessen da als GUILD.*, d.* und p.* drinstehen!
00057         case 1:
00058           // kein Punkt drin. Entweder Magier-ID oder spezielle ID
00059           // (letztere wird unten noch per tolookup nachgeguckt)
00060           if (find_userinfo(parts[0]))
00061               wizards+=({parts[0]});
00062           break;
00063     }
00064     // jetzt in userids nachschlagen
00065     foreach(uid: tolookup) {
00066         if (member(userids,uid))
00067             wizards+=userids[uid];
00068     }
00069     // so. Nun kann es aber noch sein, dass in userids sowas wie
00070     // "d.wald.atamur":({atamur}) und "atamur":({"rumata"}) drinsteht, also
00071     // ein Magier sozusagen fuer Kram eines anderen verantwortlich ist. D.h.
00072     // nochmal durch QueryWizardsForUID() schicken (das ist dann allerdings nicht
00073     // weiter rekursiv).
00074     if (!recursive) {
00075       foreach(uid: wizards) {
00076         //es ist moeglich, in der Schleife wizards zu vergroessern, ohne dass
00077         //es Einfluss auf die Schleife hat.        
00078         wizards += QueryWizardsForUID(uid, 1) - ({uid});
00079       }
00080     }
00081     return(m_indices(mkmapping(wizards)));
00082 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public string* RemoveWizardFromUID ( string  uid,
string  wizuid 
)

Definiert in Zeile 240 der Datei userinfo.c.

00240                                                               {
00241     if (!stringp(wizuid) || !strlen(wizuid)
00242         || !find_userinfo(wizuid))
00243         return(({}));
00244 
00245     //Zugriff nur als EM oder jemand, der fuer die UID zustaendig ist.
00246     if ( funcall(symbol_function('secure_level)) < ARCH_LVL 
00247         && member(
00248             QueryUIDsForWizard(funcall(symbol_function('secure_euid))),
00249             uid)==-1)
00250         return copy(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]);
00251 
00252     // jetzt muss diese wizuid aus allen UIDs in userids geloescht werden, die
00253     // sie bisher enthalten. Hierzu sollte QueryUIDAlias die potentiell
00254     // drinstehenden UIDs liefern.
00255     foreach(string tuid: QueryUIDAlias(wizuid,0)) {
00256         if (member(userids, tuid) &&
00257             member(userids[tuid],wizuid)!=-1 )
00258             userids[tuid] -= ({wizuid});
00259     }
00260     // wenn es eine UID war, fuer die der Magier explizit zustaendig war,
00261     // entsprechend loeschen. Sonst ist hier Ende.
00262     if (!pointerp(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]))
00263         return ({});
00264     if (member(userlist[wizuid,USER_UIDS_TO_TAKE_CARE],uid)==-1)
00265         return copy(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]);
00266 
00267     // Jetzt aus userlist loeschen.
00268     userlist[wizuid,USER_UIDS_TO_TAKE_CARE] -= ({uid});
00269     save_userinfo(wizuid);
00270     // und userids/uidaliase aktualisieren.
00271     QueryUIDsForWizard(wizuid);
00272     return copy(userlist[wizuid,USER_UIDS_TO_TAKE_CARE]);
00273 }

protected void save_userinfo ( string  user  ) 

Definiert in Zeile 850 der Datei userinfo.c.

Wird benutzt von set_player_object(), update_ek(), update_ektips(), update_ep(), update_fptips(), update_mq(), update_password() und update_wiz_level().

00850                                           {
00851   if(!user||user=="")
00852     return;
00853   user=explode(user,".")[0];
00854   if (!member(userlist,user)) return;
00855   name = user;
00856   level = userlist[name,USER_LEVEL];
00857   domains = userlist[name,USER_DOMAIN];
00858   shell = userlist[name,USER_OBJECT];
00859   password = userlist[name,USER_PASSWORD];
00860   creation_date = userlist[name,USER_CREATION_DATE];
00861   if (!creation_date) creation_date = -1;
00862   ep = userlist[name,USER_EP];
00863   if (!ep) ep="";
00864   ek = userlist[name,USER_EK];
00865   if (!ek) ek="";
00866   mq = userlist[name,USER_MQ];
00867   if (!mq) mq="";
00868   guilds = userlist[name,USER_GUILD];
00869   ektips=userlist[name,USER_EKTIPS];
00870   if(!ektips) ektips="";
00871   fptips=userlist[name,USER_FPTIPS];
00872   if(!fptips) fptips="";
00873   uidstotakecare=userlist[name,USER_UIDS_TO_TAKE_CARE];
00874 
00875   if (save_object(SECURESAVEPATH+name[0..0]+"/"+name) != 0) {
00876     // autsch. Buggen damit dieser moeglichst schnell auffaellt, dass hier
00877     // Savefiles in /secure/save/ nicht geschrieben wurden.
00878     raise_error(sprintf(
00879           "Savefile %O konnte nicht erstellt werden!\n",
00880           SECURESAVEPATH+name[0..0]+"/"+name));
00881   }
00882   // Savefile aus save_inactive loeschen
00883   string inactive = secure_isavefile(user);
00884   if (stringp(inactive) && strlen(inactive))
00885       rm("/"+inactive);
00886 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void save_wiz_file (  ) 

Definiert in Zeile 1087 der Datei master.c.

Benutzt wizlist_info().

01088 {
01089   rm("/WIZLIST");
01090   write_file("/WIZLIST",implode(
01091      map(wizlist_info(),#'_save_wiz_file_loop),""));
01092 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

public string secure_savefile ( string  name  ) 

Definiert in Zeile 524 der Datei userinfo.c.

Benutzt SECURESAVEPATH.

Wird benutzt von find_userinfo(), good_password(), logon2() und new_logon().

00525 {
00526   if(!name||name=="")
00527     return "";
00528   name=explode(name,".")[0];
00529   if (file_size(SECURESAVEPATH+name[0..0]+"/"+name+".o")>=0)
00530     return SECURESAVEPATH+name[0..0]+"/"+name;
00531   else if (file_size("secure/save_inactive/"+name[0..0]+"/"+name+".o")>=0)
00532     return "secure/save_inactive/"+name[0..0]+"/"+name;
00533   return "";
00534 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected void SendWizardHelpMail ( string  name,
int  level 
)

Definiert in Zeile 450 der Datei misc.c.

Wird benutzt von add_domain_master() und advance_wizlevel().

00450                                                           {
00451   
00452   object pl=funcall(symbol_function('find_player),name);
00453   if (!objectp(pl)) return;
00454 
00455   string file=sprintf("%sinfo_ml%d", WIZ_HELP_MAIL_DIR, level);
00456   // wenn kein Hilfetext fuer den Level da ist: raus
00457   if (file_size(file) <= 0)
00458     return;
00459 
00460   string subject = read_file(file,1,1);
00461   string text = funcall(symbol_function('replace_personal),
00462                          read_file(file,2), ({pl}));
00463   
00464   mixed mail = ({"Merlin", "<Master>", name, 0, 0, subject,
00465                  funcall(symbol_function('dtime),time()), 
00466                  MUDNAME+time(), text });
00467   MAILDEMON->DeliverMail(mail, 0);
00468 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected void set_domains ( string  player,
string *  domains 
)

Definiert in Zeile 889 der Datei userinfo.c.

Wird benutzt von add_domain_master() und remove_domain_master().

00890 {
00891   // wenn der Magier jetzt Domains nicht mehr hat, muessen die aus 'userids'
00892   // entfernt werden, das uebernimmt RemoveWizardFromUID().
00893   if (pointerp(userlist[player, USER_DOMAIN])) {
00894     string *removeduids=
00895       ((string*)userlist[player, USER_DOMAIN] | domains) - domains;
00896     foreach(string uid: removeduids)
00897       RemoveWizardFromUID(uid, player);
00898   }
00899   // gecachtes Alias fuer player loeschen
00900   efun::m_delete(uidaliase,player);
00901   userlist[player, USER_DOMAIN]=domains;
00902   save_userinfo(player);
00903   // UID-zu-Magier-Mapping aktualisieren
00904   QueryUIDsForWizard(player);
00905 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected void set_guilds ( string  player,
string *  guilds 
)

Definiert in Zeile 908 der Datei userinfo.c.

Wird benutzt von add_guild_master() und remove_guild_master().

00909 {
00910   // wenn der Magier jetzt Gilden nicht mehr hat, muessen die aus 'userids'
00911   // entfernt werden, das uebernimmt RemoveWizardFromUID().
00912   if (pointerp(userlist[player, USER_GUILD])) {
00913     string *removeduids=
00914       ((string*)userlist[player, USER_GUILD] | guilds) - guilds;
00915     foreach(string uid: removeduids)
00916       RemoveWizardFromUID(uid, player);
00917   }
00918   // gecachtes Alias fuer player loeschen
00919   efun::m_delete(uidaliase,player);
00920   userlist[player, USER_GUILD]=guilds;
00921   save_userinfo(player);
00922   // UID-zu-Magier-Mapping aktualisieren
00923   QueryUIDsForWizard(player);
00924 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

int TBanishName ( string  name,
int  days 
)

Definiert in Zeile 202 der Datei misc.c.

Wird benutzt von delete_player() und tbanish().

00203 {
00204   int t;
00205 
00206   if ( (getuid(TI) != name) &&
00207        !IsDeputy( funcall(symbol_function('secure_euid/*'*/)) ) )
00208     return 0;
00209 
00210   if (days && QueryTBanished(name)){
00211     write("Der Name ist schon gebannt.\n");
00212     return 0;
00213   }
00214 
00215   if (file_size(SAVEPATH+name[0..0]+"/"+name+".o")<=0){
00216     write("Es existiert kein Spieler dieses Namens!\n");
00217     return 0;
00218   }
00219 
00220   if (!days && member(tbanished, name))
00221     efun::m_delete(tbanished, name);
00222   else {
00223     if (!mappingp(tbanished))
00224       tbanished = ([]);
00225     if (days <= -1)
00226       t = -1;
00227     else
00228       t = (time()/86400)*86400 + days*86400;
00229     tbanished += ([ name : t ]);
00230   }
00231 
00232   UpdateTBanish();
00233   return 1;
00234 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void update_late_players (  ) 

Definiert in Zeile 811 der Datei userinfo.c.

00811                            {
00812   string read;
00813   string *tmp;
00814   
00815   lateplayers=0;
00816   
00817   read=read_file("/secure/LATE_PLAYERS");
00818   if(!read || read=="")
00819   {
00820     return;
00821   }
00822   
00823   tmp=explode(read,"\n");
00824   if(!sizeof(tmp))
00825   {
00826     return;
00827   }         
00828   
00829   lateplayers=tmp; 
00830 }

int update_wiz_level ( string  user,
int  lev 
)

Definiert in Zeile 551 der Datei userinfo.c.

Benutzt find_userinfo(), ob(), PO, ROOTID, save_userinfo(), USER_LEVEL und userlist.

Wird benutzt von add_domain_master() und advance_wizlevel().

00551                                           {
00552   object ob;
00553 
00554   if (getuid(PO) != ROOTID && extern_call()) return 0;
00555   if (!find_userinfo(user)) return 0;
00556   userlist[user,USER_LEVEL] = lev;
00557   save_userinfo(user);
00558   return 1;
00559 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mixed valid_read ( string  path,
string  euid,
string  fun,
object  obj 
)

Definiert in Zeile 348 der Datei file_access.c.

Benutzt access_rights(), ARCH_LVL, ctime(), deputy_files, DOCDIR, domain_master(), DOMAINDIR, ELDER_LVL, ETCDIR, FTPDIR, full_path_array(), GUILDDIR, insecure, IS_DEPUTY, LIBLOGDIR, LIBOBJDIR, LIBROOMDIR, LIBSAVEDIR, LORD_LVL, MAILDIR, MAILID, NEWSDIR, project_access(), PROJECTDIR, query_wiz_level(), READ_FILE, ROOTID, SECUREDIR, SPELLBOOKDIR, STDDIR, SYSDIR, TO, WIZARD_LVL und WIZARDDIR.

Wird benutzt von FtpAccess().

00349 {
00350   int s, lev;
00351   string *strs, suf;
00352 
00353   // einige Funktionen im Driver sind crash-anfaellig bei grossen Strings als
00354   // Dateinamen. Als Work-Around alle Strings als Pfad ablehnen, die laenger
00355   // als 2kb sind.
00356   // TODO: nach Driverreparatur entfernen.
00357   if (strlen(path) > 2048) return 0;
00358 
00359   if (member(path,' ')!=-1) return 0;
00360 
00361   if (!euid) euid="-";
00362 
00363   strs=full_path_array(path, euid);
00364   // Pfad soll ab jetzt auf jeden Fall absolut sein.
00365   if (strs[0] != "")
00366       path = "/" + implode(strs, "/");
00367   else
00368       path=implode(strs, "/");
00369 
00370   // fuer die Rechtebestimmung "/" an Anfang und Ende entfernen
00371   strs -= ({""});
00372 
00373   if (!sizeof(strs) || !strlen(path) || euid == ROOTID || obj==TO) return path;
00374 
00375   if ((s=sizeof(strs)) <= 1) return path;
00376 
00377   lev=query_wiz_level(euid);
00378 
00379   switch(strs[0]) {
00380     case "core":
00381     case "wahl":
00382     case NEWSDIR:
00383       return 0;
00384 
00385 //    case "pub":
00386 //        if ( lev < WIZARD_LVL )
00387 //            return 0;
00388 
00389     case "maps":
00390       if (lev<=WIZARD_LVL) return 0;
00391 
00392     case "":
00393     case ETCDIR:
00394     case STDDIR:
00395     case SYSDIR:
00396     case DOCDIR:
00397     case LIBOBJDIR:
00398     case LIBROOMDIR:
00399     case FTPDIR:
00400       return path;
00401 
00402     case MAILDIR:
00403       return (euid==MAILID);
00404 
00405     case SECUREDIR:
00406       if (strs[1]=="save" || strs[1]=="save_inactive") return 0;
00407       if (path[<2..]==".o" || path[<5..]==".dump") return 0;
00408       if (strs[1]!="ARCH" || lev>=ARCH_LVL) return path;
00409 
00410     case LIBLOGDIR:
00411       if ( strs[1] == "ARCH" && !IS_DEPUTY(euid) )
00412           return 0;
00413 
00414       if ( strs[1] == "ARCH" && lev < ARCH_LVL && s == 3 &&
00415            strs[2] != "*" && strs[2][0..2] != "bb." &&
00416            member( deputy_files, strs[2] ) < 0 )
00417           return 0;
00418 
00419       if ( lev > WIZARD_LVL )
00420           return path;
00421 
00422       if ( s == 2 && (strs[1] == "report" || strs[1] == "error") )
00423           return path; // fuer 'cd'
00424 
00425       // /log sollte jeder auflisten koennen
00426       if ( s == 2 && strs[1]=="*" && fun=="get_dir")
00427           return path;
00428 
00429       // unter /log/report/, /log/error und /log/warning/ duerfen alle lesen
00430       if ( s==3 && 
00431           (strs[1] == "report" || strs[1] == "error"  
00432            || strs[1] =="warning"))
00433           return path;
00434 
00435       // /log/<Magiername> darf von <Magiername> natuerlich auch
00436       // gelesen werden
00437       if ( s >= 2 && strs[1] == euid )
00438           return path;
00439 
00440       return 0;
00441 
00442     case "backup":
00443     case LIBSAVEDIR:
00444       if (lev>WIZARD_LVL) return path;
00445 
00446       /* Objekte in /p/* haben bisher leider wizlevel 0 */
00447       //if (lev==0) return path;
00448 
00449       if (fun=="file_size") return path;
00450 
00451       // das eigene Savefile darf man natuerlich immer. ;-)
00452       if (s==3 && (strs[2]==euid+".o" || strs[2]==euid))
00453         return path;
00454       return 0;
00455 
00456     case PROJECTDIR:
00457       /* Pruefen ob ein File existiert darf jeder... */
00458       if (fun=="file_size") return path;
00459 
00460       /* Die Service-Verzeichnisse darf jeder lesen */
00461       if (s>3 && strs[1]=="service") return path;
00462 
00463       //Weise duerfen in /p/ schreiben, also auch lesen. (Zesstra, 04.11.06)
00464       if (lev>=ELDER_LVL) return path;
00465 
00466       /* wer hier schreiben darf, darf natuerlich auf jeden Fall lesen */
00467       //Anmerkung v. Zesstra: das prueft nur, ob jemand in ACCESS_RIGHTS
00468       //steht, nicht ob jemand (ggf. aus anderen Gruenden schreiben darf)
00469       if (project_access(euid,strs[1])) return path;
00470       //Alternativ kann man explizite Schreibrechte auch via access_rights.c
00471       //vergeben. (und damit natuerlich auch Leserechte)
00472       if (access_rights(strs,euid)>0) return path;
00473 
00474       /* Objekte eines Projektes haben Lesezugriff auf ihr Projekt */
00475       if (s>3 && (implode(strs[0..1], ".") == euid
00476                   || implode(strs[0..2], ".") == euid) ) return path;
00477 
00478       /* Fall-Through */
00479 
00480     case GUILDDIR:
00481       /* "secure"-Verzeichnisse darf nur lesen, wer da auch schreiben darf */
00482       if ( s > 3 && strs[<2] == "secure" && member( insecure, strs[1] ) < 0
00483            && lev < ARCH_LVL && !access_rights(strs, euid) )
00484           return 0;
00485 
00486       /* Pruefen ob ein File existiert darf jeder... */
00487       if (fun=="file_size") return path;
00488 
00489       /* Fall-Through */
00490 
00491     case SPELLBOOKDIR:
00492       // Gildenpbjekte koennen hier lesen
00493       if (lev==0 && euid[0..4]=="GUILD") return path;
00494 
00495       // Mit Level <= 20 darf man hier nichts lesen
00496       if ( lev<=WIZARD_LVL && sizeof(regexp( ({strs[<1]}), "\\.[och]" )) )
00497         return 0;
00498 
00499       return path;
00500 
00501     case WIZARDDIR:
00502       if (s==2) return path;
00503       /* das eigene Verzeichniss darf man natuerlich immer lesen... */
00504       if (strs[1]==euid && lev>=WIZARD_LVL) return path;
00505 
00506       /* Pruefen ob ein File existiert darf jeder... */
00507       if (fun=="file_size") return path;
00508 
00509       /* fremde Verzeichnisse mit <= Level 20 noch nicht */
00510       if (lev<=WIZARD_LVL) return 0;
00511 
00512       /* wo man schreiben darf, darf man natuerlich auch lesen... */
00513       if (lev>=ELDER_LVL) return path;
00514 
00515       // kein Zugriff auf archivierten Code (wo z.B. secure/ drin sein
00516       // koennen)
00517       if (member(({"bz2","gz","zip"}), explode(strs[<1],".")[<1]) > -1)
00518         return 0;
00519 
00520       /* Files ohne Code sind nicht weiter interessant... */
00521       if ( !sizeof(regexp( ({strs[<1]}), "\\.[och]" )) )
00522           return path;
00523 
00524       /* folgende Funktionen sind natuerlich voellig uninteressant */
00525       if (member(({"get_dir", "restore_object"}), fun)!=-1)
00526           return path;
00527 
00528       /* Zugriff erlaubt, aber mitloggen */
00529       write_file( READ_FILE, sprintf("%O %s %s: %s\n", fun, ctime()[4..],
00530                                      euid, path) );
00531       return path;
00532 
00533     case DOMAINDIR:
00534       /* Mit Level 15 darf man hier _nichts_ lesen */
00535       if ( fun!="file_size" && lev<WIZARD_LVL &&
00536            sizeof(regexp( ({strs[<1]}), "\\.[och]" )) ) return 0;
00537 
00538       /* den Verzeichnisbaum von /d/ darf man natuerlich sonst lesen */
00539       if (s<=2) return path;
00540 
00541       /* eigenen Code darf man natuerlich auch lesen */
00542       if (euid==strs[2] || euid==sprintf("d.%s.%s", strs[1], strs[2]))
00543          return path;
00544 
00545       /* Deputies haben ein gemeinsames Verzeichnis unter /d/erzmagier */
00546       if (strs[1]=="erzmagier" && strs[2]=="polizei" && IS_DEPUTY(euid))
00547           return path;
00548 
00549       /* d/erzmagier darf man nur als Erzmagier lesen */
00550       if (strs[1]=="erzmagier" && lev<ARCH_LVL) return 0;
00551 
00552       /* einige Regionen haben std-verzeichnisse, die darf man natuerlich
00553          auch mit Level 20 bereits komplett lesen! */
00554       if (strs[2]=="std") return path;
00555 
00556       /* "secure"-Verzeichnisse darf nur lesen, wer da auch schreiben darf */
00557       if ( s > 4 && strs[<2] == "secure" && member( insecure, strs[2] ) < 0 ){
00558           if ( lev < ELDER_LVL && !domain_master(euid, strs[1])
00559                && !access_rights(strs, euid) )
00560               return 0;
00561           else
00562               return path;
00563       }
00564 
00565       /* Dokus, Infos und .readme darf man immer lesen... */
00566       if ( fun=="file_size" || !sizeof(regexp( ({strs[<1]}), "\\.[och]" )) )
00567           return path;
00568 
00569       /* Mit Level 20 darf man noch keinen fremden Code lesen! */
00570       if (lev<=WIZARD_LVL) return 0;
00571 
00572       /* Weise duerfen natuerlich alles weitere lesen */
00573       if (lev>=ELDER_LVL) return path;
00574 
00575       /* Regionsmagier in ihren Regionen natuerlich auch */
00576       if (lev>=LORD_LVL && domain_master(euid, strs[1])) return path;
00577 
00578       /* folgende Funktionen sind natuerlich voellig uninteressant */
00579       if (member(({"get_dir", "restore_object"}), fun)!=-1)
00580           return path;
00581 
00582       /* Zugriff erlaubt, aber mitloggen */
00583       write_file( READ_FILE, sprintf("%O %s %s: %s\n", fun, ctime()[4..],
00584                                      euid, path) );
00585       return path;
00586   }
00587   if (lev<ARCH_LVL) return 0;
00588   return path;
00589 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mixed valid_write ( string  path,
string  euid,
string  fun,
object  obj 
)

Definiert in Zeile 153 der Datei file_access.c.

Benutzt access_rights(), ARCH_LVL, creator_file(), DOCDIR, domain_master(), domain_member(), DOMAINDIR, ELDER_LVL, ETCDIR, FTPDIR, full_path_array(), get_wiz_level(), GUILDDIR, IS_WIZARD, LIBLOGDIR, LIBOBJDIR, LIBROOMDIR, LIBSAVEDIR, MAILDIR, MAILID, project_access(), PROJECTDIR, query_wiz_level(), ROOTID, SPECIAL_LVL, SPELLBOOKDIR, STDDIR, SYSDIR, TMPDIR, TO, WIZARD_LVL und WIZARDDIR.

Wird benutzt von FtpAccess().

00154 {
00155   int s,lvl;
00156   string *strs;
00157   int *date;
00158 
00159   // einige Funktionen im Driver sind crash-anfaellig bei grossen Strings als
00160   // Dateinamen. Als Work-Around alle Strings als Pfad ablehnen, die laenger
00161   // als 2kb sind.
00162   // TODO: nach Driverreparatur entfernen.
00163   if (strlen(path) > 2048) return 0;
00164 
00165   if (member(path,' ')!=-1) return 0;
00166 
00167   switch(fun) {
00168     case "log_file":
00169       strs=full_path_array("/"+path, 0);
00170       path = implode(strs, "/");
00171       strs -= ({""}); // remove trailing and leading "/".
00172       if (sizeof(strs)>1 && strs[0]=="log") return path;
00173       return 0;
00174     case "save_object":
00175       if (!path) return 0;
00176       strs=full_path_array("/"+path, 0);
00177       break;
00178     case "ed_start":
00179       if (path && path[0])
00180         strs=full_path_array(path, euid);
00181       else strs=({"players",euid,".err"});
00182       break;
00183     default:
00184       strs=full_path_array(path, euid);
00185   }
00186 
00187   if (!euid || euid=="NOBODY" || euid=="ftp" || euid=="anonymous") return 0;
00188 
00189   // Pfad soll ab jetzt auf jeden Fall absolut sein.
00190   if (strs[0] != "")
00191       path = "/" + implode(strs, "/");
00192   else
00193       path=implode(strs, "/");
00194 
00195   // fuer die Rechtebestimmung "/" an Anfang und Ende entfernen
00196   strs -= ({""});
00197 
00198   //Root-Objekte und Master duerfen immer.
00199   if (euid == ROOTID || obj==TO) return path;
00200 
00201   lvl=query_wiz_level(euid);
00202 
00203   //Toplevel: nur EM+
00204   if ((s=sizeof(strs))<=1) return lvl>=ARCH_LVL;
00205 
00206   switch(strs[0]) {
00207     case TMPDIR:
00208       return 1;
00209 
00210 //    case "pub":
00211 //      return lvl>=WIZARD_LVL;
00212 
00213     case STDDIR:
00214     case SYSDIR:
00215     case LIBOBJDIR:
00216     case ETCDIR:
00217     case LIBROOMDIR:
00218       return lvl>=ARCH_LVL;
00219 
00220     case SPELLBOOKDIR:
00221     case GUILDDIR:
00222       return ((lvl>=ARCH_LVL) || access_rights(strs,euid));
00223 
00224     case DOCDIR:
00225       if ( s > 1 && (strs[1] == "balance") )
00226         return ((lvl>=ARCH_LVL) || access_rights(strs,euid));
00227       else
00228         return ((lvl>=SPECIAL_LVL) || access_rights(strs,euid));
00229 
00230     case FTPDIR:
00231         if ( s > 1 && (strs[1] == "incoming" || strs[1] == "tmp" ||
00232                        s == 3 && strs[1] == "News" && strs[2] == euid+".news") )
00233             return 1;
00234 
00235         if (lvl>=ELDER_LVL)
00236             return 1;
00237 
00238         return 0;
00239 
00240     case MAILDIR:
00241       if (euid==MAILID || strs[1]=="spool") break;
00242       return 0;
00243 
00244     case LIBSAVEDIR:
00245       if (lvl>=ARCH_LVL) return 1;
00246       if (s==3 && strs[1] == euid[0..0] &&
00247           (strs[2]==euid+".o" || strs[2]==euid)) break;
00248       return 0;
00249 
00250     case LIBLOGDIR:
00251       /* auf /log/ARCH/ haben wirklich nur EMs Zugriff */
00252       if (strs[1]=="ARCH" && lvl<ARCH_LVL) return 0;
00253 
00254       /* alles andere duerfen auch Weise... */
00255       if (lvl>=ELDER_LVL) return 1;
00256 
00257       /* Allgemeine logfiles in /log duerfen wirklich nur geschrieben werden */
00258       if (s==2 && strs[1][0]>='A' && strs[1][0]<='Z' && fun != "write_file")
00259          return 0;
00260 
00261       /* Unterhalb von /log/syslog darf nur geschrieben werden */
00262       if (s>1 && strs[1]=="syslog" && fun != "write_file")
00263          return 0;
00264 
00265       /* loggen ins eigene repfile immer erlauben */
00266       if (s==3 && strs[1]=="report" &&
00267           strs[2]==explode(euid, ".")[<1]+".rep") break;
00268 
00269       /* in fremden Verzeichnissen hat niemand was zu loggen */
00270       if (get_wiz_level(strs[1]) >= WIZARD_LVL &&
00271           strs[1] != efun::explode(euid, ".")[<1])
00272          return 0;
00273       break;
00274 
00275     case WIZARDDIR:
00276       /* kein Zugriff auf Objekte mit hoeheren Rechten */
00277       if (query_wiz_level(strs[1]) > lvl) return 0;
00278 
00279       /* Magier selbst oder Weise duerfen hier schreiben */
00280       if ((IS_WIZARD(euid) && euid==strs[1])||(lvl>=ELDER_LVL)) break;
00281 
00282       /* Es steht jedoch frei, auch anderen Schreibrechte zu geben... */
00283       return access_rights(strs,euid);
00284       
00285     case DOMAINDIR:
00286       /* neue Regionen duerfen nur Erzmagier anlegen */
00287       if (s<2 && lvl<ARCH_LVL) return 0;
00288 
00289       /* kein Zugriff auf Objekte mit hoeheren Rechten */
00290       if (s>2 && query_wiz_level(creator_file(path)) > lvl)
00291          return 0;
00292 
00293       /* Auf Regionfiles von erzmagier haben nur EMs Zugriff */
00294       if (creator_file(path)=="erzmagier" && lvl<ARCH_LVL) return 0;
00295 
00296       /* innerhalb der Region haben RMs und Weise volle Schreibrechte */
00297       if (lvl>=ELDER_LVL || domain_master(euid,strs[1])) break;
00298 
00299       /* neue Verzeichnisse in der Region kann nur RM+ anlegen */
00300       if (s<=3 && (fun=="mkdir" || fun=="rmdir")) return 0;
00301 
00302       /* Magier auf ihre eigenen Files... */
00303       if (s>2 && strs[2]==euid) break;
00304 
00305       /* Files der Magier in der Region in ihre eigenen Verzeichnisse... */
00306       if (s>2 && euid==sprintf("d.%s.%s", strs[1], strs[2])) break;
00307 
00308       /* Files mit Regionsuid */
00309       if (euid==strs[1]) break;
00310 
00311       /* Es ist moeglich anderen Magiern Rechte bei sich einzuraeumen. */
00312       if (access_rights(strs,euid)>0) break;
00313 
00314       /* Auf das Verzeichniss 'alle' haben alle Regionsmitglieder Zugriff.
00315          Ausser, wenn sie ueber access_rights.c explizit ausgeschlossen
00316          werden (Returncode < 0). */
00317       if (s>2 && strs[2]=="alle" && domain_member(euid, strs[1]) &&
00318           access_rights(strs,euid)>=0) break;
00319       return 0;
00320 
00321     case PROJECTDIR:
00322       /* Nur Erzmagier duerfen neue Projektverzeichnisse anlegen... */
00323       if (s<3 && lvl<ARCH_LVL) return 0;
00324 
00325       /* alles weitere duerfen auch Weise tun */
00326       if (lvl>=ELDER_LVL) break;
00327 
00328       /* in den Serviceverzeichnissen muss lediglich der Name stimmen */
00329       if (s>3 && strs[1]=="service" && euid==strs[2]) break;
00330 
00331       /* Objekte eines Projektes haben Schreibzugriffe auf ihr Projekt */
00332       if (s>3 && (implode(strs[0..1], ".") == euid
00333                   || implode(strs[0..2], ".") == euid) ) return 1;
00334 
00335       /* Schreibrechte koennen natuerlich auch vergeben werden... */
00336       if (project_access(euid,strs[1])) break;
00337       // Alternativ besteht neben dem ACCESS_RIGHTS auch noch die
00338       // Moeglichkeit, per access_rights.c Rechte einzuraeumen.
00339       if (access_rights(strs,euid)>0) break;
00340 
00341      return 0;
00342 
00343     default: return 0;
00344   }
00345   return path;
00346 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

Erzeugt am Thu Jun 3 14:41:29 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3