master.c-Dateireferenz

#include "/sys/files.h"
#include "/secure/master.h"
#include "/sys/rtlimits.h"
#include "/sys/debug_info.h"
#include "/sys/debug_message.h"
#include "/secure/master/destruct.c"
#include "/secure/master/autoinclude.c"
Include-Abhängigkeitsdiagramm für master.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define RESETINT   3600
#define LOGROTATE   (24*2)
#define LOGFILEAGE   (RESETINT*LOGROTATE)
#define LOGNUM   3

Funktionen

protected void inaugurate_master (int arg)
protected string * epilog (int eflag)
protected void preload (string file)
protected string * get_simul_efun ()
void redo_preload ()
public varargs int remove (int silent)
protected void reset ()
string creator_file (mixed str)
protected mixed give_uid_to_object (string datei, object po)
string get_master_uid ()
string get_bb_uid ()
string get_wiz_name (string file)
protected object connect ()
protected void disconnect (object who, string remaining)
protected object compile_object (string filename)
protected void remove_player (object victim)
protected void slow_shut_down (int minutes)
protected varargs void notify_shutdown (string crash_reason)
int valid_exec (string name, object ob, object obfrom)
int valid_snoop (object me, object you)
int valid_query_snoop (object wiz)
int valid_seteuid (object ob, string neweuid)
int valid_trace (string what, mixed arg)
int query_allow_shadow (object ob)
int privilege_violation (string op, mixed who, mixed arg1, mixed arg2)
protected int heart_beat_error (object culprit, string error, string program, string current_object, int line, int caught)
protected int log_error (string file, string message, int warn)
 Error handling fuer Fehler beim Compilieren.
private void handle_runtime_error (string err, string prg, string curobj, int line, mixed culprit, int caught, object po, string hashkey)
private void call_runtime_error (string err, string prg, string curobj, int line, mixed culprit, int caught, object po)
protected void runtime_error (string err, string prg, string curobj, int line, mixed culprit, int caught)
protected void runtime_warning (string msg, string curobj, string prog, int line, int inside_catch)
protected int save_ed_setup (object who, int code)
protected int retrieve_ed_setup (object who)
string get_ed_buffer_save_file_name (string file)
protected void external_master_reload ()
protected void flag (string str)
protected void stale_erq (closure callback)
protected void reactivate_destructed_master (int flag)
protected void quota_demon ()
string printf_obj_name (object ob)
static string _save_wiz_file_loop (mixed *a)
protected void save_wiz_file ()
void telnet_neg (mixed cmd, mixed opt, mixed args)
protected mixed load_uid_hook (string datei)
protected mixed clone_uid_hook (string blueprint, string new_name)

Variablen

inherit secure master misc
inherit secure master userinfo
inherit secure master network
inherit secure master domain
inherit secure master guild
inherit secure master file_access
inherit secure master players_deny
static int logrotate_counter

Makro-Dokumentation

#define LOGFILEAGE   (RESETINT*LOGROTATE)

Definiert in Zeile 42 der Datei master.c.

#define LOGNUM   3

Definiert in Zeile 43 der Datei master.c.

#define LOGROTATE   (24*2)

Definiert in Zeile 41 der Datei master.c.

#define RESETINT   3600

Definiert in Zeile 40 der Datei master.c.


Dokumentation der Funktionen

static string _save_wiz_file_loop ( mixed *  a  )  [static]

Definiert in Zeile 1081 der Datei master.c.

Benutzt WL_COMMANDS, WL_EXTRA und WL_NAME.

01082 {
01083   return sprintf("%s %d %d\n",a[WL_NAME],a[WL_COMMANDS],a[WL_EXTRA]);
01084 }

private void call_runtime_error ( string  err,
string  prg,
string  curobj,
int  line,
mixed  culprit,
int  caught,
object  po 
)

Definiert in Zeile 923 der Datei master.c.

Benutzt handle_runtime_error().

00924                                                     {
00925     string hashkey;
00926 
00927     //Fehlerdaten an den Errord zur Speicherung weitergeben, falls wir sowas
00928     //haben.
00929 #ifdef ERRORD
00930     catch(hashkey=limited(#'call_other,({200000}),ERRORD,"LogError",
00931           err,prg,curobj,line,culprit,caught);publish);
00932 #endif // ERRORD
00933 
00934     //eigenen Errorhandler laufzeitbegrenzt rufen
00935     limited(#'handle_runtime_error, ({ 200000 }), err, prg, curobj,
00936         line,culprit,caught, po, hashkey);
00937 }

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

protected 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:

protected object compile_object ( string  filename  ) 

Definiert in Zeile 534 der Datei master.c.

Benutzt creator_file() und REAL_EUID.

00535 {
00536   object ret;
00537   string *str;
00538   string compiler;
00539 
00540   if (!strlen(filename)) return 0;
00541   str=efun::explode(filename,"/");
00542 
00543   if(sizeof(str)<2) return 0;
00544   compiler=implode(str[0..<2],"/")+"/virtual_compiler";
00545  
00546   if (file_size(compiler+".c")>0)
00547   {
00548     if(catch(
00549           ret=(object)call_other(compiler,"compile_object",str[<1]); publish))
00550       return 0;
00551   }
00552   else
00553       return(0);
00554 
00555   if ( objectp(ret) && efun::explode(creator_file(filename), ".")[<1] !=
00556        REAL_EUID(ret) ){
00557       funcall( symbol_function('log_file/*'*/), "ARCH/VC_MISSBRAUCH",
00558                sprintf( "%s: %s versucht per VC %s zu %s umzubenennen!\n",
00559                         funcall( symbol_function('dtime/*'*/), time() ),
00560                         (this_interactive() ? getuid(this_interactive()):
00561                          object_name(previous_object())), object_name(ret),
00562                          filename) );
00563 
00564       return 0;
00565   }
00566   return ret;
00567 }

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

protected object connect (  ) 

Definiert in Zeile 484 der Datei master.c.

00485 {
00486   string err;
00487   int errno;
00488   object ob,bp;
00489 
00490 #if defined(SSLPORT) && __EFUN_DEFINED__(tls_available)
00491   if (query_mud_port() == SSLPORT) {
00492     // reject connection of TLS is not available
00493     if (!tls_available())
00494       return 0;
00495     // establish TLS
00496     errno=tls_init_connection();
00497     if (errno < 0) {
00498       // Fehler im Vebindungsaufbau
00499       printf("Can't establish a TLS/SSL encrypted connection: %s\n",
00500           tls_error(errno));
00501       return 0; // this will close the connection to the client.
00502     }
00503   }
00504 #endif
00505   // if err is > 0, the TLS connection is still being established in the
00506   // background. We must not send any data to the client.
00507   if (errno == 0) {
00508     printf("HTTP/1.0 302 Found\n"
00509          "Location: http://mg.mud.de/\n\n"
00510          "NetCologne, Koeln, Germany. Local time: %s\n\n"
00511          MUDNAME" LDmud, NATIVE mode, driver version %s\n\n",
00512          strftime("%c"), __VERSION__);
00513   }
00514 
00515   // Blueprint im Environment? Das geht nun wirklich nicht ...
00516   if ((bp=find_object("/secure/login")) && environment(bp)) 
00517       catch(destruct(bp);publish);
00518 
00519   // Login-Shell clonen
00520   err = catch(ob = clone_object("secure/login"); publish);
00521 
00522   if (errno == 0 && err)
00523       write("Fehler beim Laden von /secure/login.c\n"+err+"\n");
00524 
00525   return ob;
00526 }

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:

protected void disconnect ( object  who,
string  remaining 
)

Definiert in Zeile 529 der Datei master.c.

00529                                                         {
00530     who->NetDead(); return;
00531 }

protected string* epilog ( int  eflag  ) 

Definiert in Zeile 180 der Datei master.c.

Benutzt ctime(), domains, explode_files(), get_domains(), i, ReloadBanishFile(), ReloadDeputyFile(), ReloadInsecureFile() und ROOTID.

00180                                     {
00181   string *files, *domains;
00182   int i;
00183 
00184   seteuid(ROOTID);
00185   ReloadBanishFile();
00186   ReloadDeputyFile();
00187   ReloadInsecureFile();
00188 
00189   if (eflag) {
00190     write("-e angegeben -> Preloading unterdrueckt ...\n");
00191     return 0;
00192   }
00193 
00194   printf("Preloading gestartet: %s\n\n",ctime(time()));
00195 
00196   //Files fuers Preloading und Regionen holen
00197   files=explode_files("/std/preload_file") + explode_files("/d/preload_file");
00198   domains=get_domains() + ({"erzmagier"}); // EM haben auch ein Preload File
00199 
00200   for (i=sizeof(domains);i--;)
00201     files+=explode_files("/d/"+domains[i]+"/preload_file");
00202   
00203   write("\n");
00204  
00205   return files;
00206 }

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

protected void external_master_reload (  ) 

Definiert in Zeile 1034 der Datei master.c.

01034 { return; }

protected void flag ( string  str  ) 

Definiert in Zeile 1037 der Datei master.c.

01037 { return; }

string get_bb_uid (  ) 

Definiert in Zeile 474 der Datei master.c.

00474 { return BACKBONEID; }

string get_ed_buffer_save_file_name ( string  file  ) 

Definiert in Zeile 1023 der Datei master.c.

01024 {
01025   return sprintf("/players/%s/.dead_ed_files/%s",
01026                  getuid(this_player()),efun::explode(file, "/")[<1]);  
01027 }

string get_master_uid (  ) 

Definiert in Zeile 473 der Datei master.c.

00473 { return ROOTID;}

protected string* get_simul_efun (  ) 

Definiert in Zeile 262 der Datei master.c.

00262                                    {
00263   string err;
00264 
00265   if (!(err=catch(SIMUL_EFUN_FILE->start_simul_efun())) )
00266     return ({SIMUL_EFUN_FILE});
00267   
00268   write("Failed to load simul efun " + SIMUL_EFUN_FILE + "\n");
00269   debug_message("Failed to load simul efun " + SIMUL_EFUN_FILE +
00270       " " + err, DMSG_STDOUT | DMSG_LOGFILE);
00271 
00272   if (!(err=catch(SPARE_SIMUL_EFUN_FILE->start_simul_efun())) )
00273     return ({SPARE_SIMUL_EFUN_FILE});
00274   
00275   write("Failed to load spare simul efun" + SPARE_SIMUL_EFUN_FILE + "\n");
00276   debug_message("Failed to load spare simul efun " + SPARE_SIMUL_EFUN_FILE +
00277       " " + err, DMSG_STDOUT | DMSG_LOGFILE);
00278 
00279  
00280   efun::shutdown();
00281   
00282   return 0;
00283 }

string get_wiz_name ( string  file  ) 

Definiert in Zeile 477 der Datei master.c.

00477 { return creator_file(file);}

protected 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:

private void handle_runtime_error ( string  err,
string  prg,
string  curobj,
int  line,
mixed  culprit,
int  caught,
object  po,
string  hashkey 
)

Definiert in Zeile 871 der Datei master.c.

Benutzt code, DEBUG2_MSG, DEBUG_MSG, destruct(), IS_LEARNER, P_TESTPLAYER, TI und TP.

Wird benutzt von call_runtime_error().

00872                                                                     {
00873   string code;
00874   string debug_txt;
00875   object ob, titp; 
00876 
00877   //DEBUG(sprintf("Callerstack: (handle_runtime_error()): %O\n",
00878   //        caller_stack(1)));
00879   // Fehlermeldung bauen
00880   if (!stringp(err))    err="<NULL>";
00881   if (!stringp(prg))    prg="<NULL>";
00882   if (!stringp(curobj)) curobj="<NULL>";
00883   debug_txt=sprintf("Fehler: %O, Objekt: %s, Programm: %O, Zeile %O (%s), "
00884                     "ID: %s",
00885                     err[0..<2], curobj, (prg[0]!='<'?"/":"")+prg, line,
00886                     (TI?capitalize(getuid(TI)):"<Unbekannt>"),
00887                     hashkey||"");
00888   
00889   titp = TI || TP;
00890   // Fehlermeldung an Kanaele schicken
00891   if (titp && (IS_LEARNER(titp) || (titp->QueryProp(P_TESTPLAYER))))
00892     DEBUG2_MSG(debug_txt,po); // -entw
00893   else
00894     DEBUG_MSG(debug_txt,po);  // -Debug
00895   if (!titp) return;
00896 
00897   // Fehlermeldung an Benutzer
00898   if (IS_LEARNER(titp))
00899     tell_object(titp,
00900                 sprintf("%'-'78.78s\nfile: %s line: %d object: %s\n" +
00901                         "%serror: %s%'-'78.78s\n","",prg,line,curobj,
00902                         (prg&&(code=read_file("/"+prg,line,1))?
00903                          "\n"+code+"\n":""),err,""));
00904   else
00905     write("Du siehst einen Fehler im Raum-Zeit-Gefuege.\n");
00906 
00907   // Wenn Magierclosure zerstoert wurde: Magier zerstoeren
00908   // TODO: Ist das gewollt?
00909   if (err=="Object the closure was bound to has been destructed\n")
00910   {
00911     ob=find_object(curobj);
00912     if (ob && IS_LEARNER(ob) && query_once_interactive(ob))
00913     {
00914       ob->quit();
00915       if (ob) catch(ob->remove(); publish);
00916       if (ob) destruct(ob);
00917     }
00918   }
00919   return;
00920 }

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

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

protected int heart_beat_error ( object  culprit,
string  error,
string  program,
string  current_object,
int  line,
int  caught 
)

Definiert in Zeile 788 der Datei master.c.

00790 {
00791   if (!objectp(culprit)) return 0;
00792   if (interactive(culprit))
00793   {
00794     tell_object(culprit,"Der GameDriver teilt Dir mit: "
00795                 "Dein Herzschlag hat ausgesetzt!\n");
00796     if (IS_LEARNER(culprit))
00797       tell_object(culprit,
00798                   sprintf("Fehler: %sProgamm: %s, CurrObj: %s, Zeile: %d, "
00799                     "the error was %scaught at higher level.\n",
00800                     error,program,current_object,line,
00801                     caught ? "" : "not"));
00802   }
00803 
00804   if (query_once_interactive(culprit))
00805     call_out("restart_heart_beat", 5, culprit);
00806   else
00807     catch(culprit->make_immortal(); publish);
00808   return 0;
00809 }

protected void inaugurate_master ( int  arg  ) 

Definiert in Zeile 56 der Datei master.c.

Benutzt create(), DEBUG, dest(), H_AUTO_INCLUDE, H_CLONE_UIDS, item, load_uid_hook(), LoadPLDenylists(), ob(), ROOTID und set_this_player().

00056                                           {
00057 
00058   seteuid(ROOTID);
00059   userinfo::create();
00060   LoadPLDenylists();
00061 
00062   // Was soll vor jede Datei geschrieben werden?
00063   set_driver_hook(H_AUTO_INCLUDE, #'autoincludehook);
00064 
00065   //div. Listen einlesen
00066   ReloadBanishFile();
00067   ReloadDeputyFile();
00068   ReloadInsecureFile();
00069  
00070   // Bei Neustart wizinfo initialisieren
00071   if (!arg)
00072     set_extra_wizinfo(0, allocate(BACKBONE_WIZINFO_SIZE));
00073   
00074   //simul_efun.c nach inaugurate_master() starten und initialisieren, 
00075   //(so richtig seh ich den Sinn hier momentan nicht ein...
00076   //call_out("start_simul_efun",0);
00077 
00078   // Reset festsetzen (1h)
00079   set_next_reset(RESETINT);
00080 
00081 
00082   // Hooks setzen
00083   
00084   // Standardincludeverzeichnisse fuer #include <>
00085   set_driver_hook(H_INCLUDE_DIRS, ({"secure/","sys/"}) );
00086   
00087   //Nach dem Laden/Clonen create() im Objekt rufen
00088   set_driver_hook(H_CREATE_CLONE,       "create");
00089   set_driver_hook(H_CREATE_OB,          "create");
00090   set_driver_hook(H_CREATE_SUPER,       "create_super");
00091 
00092   // Bei Reset reset() im Objekt aufrufen
00093   set_driver_hook(H_RESET,              "reset");
00094   
00095   // Zum Aufraeumen clean_up() im Objekt aufrufen  
00096   set_driver_hook(H_CLEAN_UP,           "clean_up");
00097 
00098   // Jede Eingabe wird ueber modify_command gelenkt
00099   set_driver_hook(H_MODIFY_COMMAND,       "modify_command");
00100   set_driver_hook(H_MODIFY_COMMAND_FNAME, "modify_command");
00101 
00102   // Standard-Fehlermeldung
00103   //set_driver_hook(H_NOTIFY_FAIL,        "Wie bitte?\n");
00104   set_driver_hook(H_NOTIFY_FAIL, function string (string cmd, object tp)
00105       {if (stringp(cmd=(string)tp->QueryProp(P_DEFAULT_NOTIFY_FAIL)))
00106          return(cmd);
00107        return("Wie bitte?\n");});
00108 
00109   // Was machen bei telnet_neg
00110   set_driver_hook(H_TELNET_NEG,"telnet_neg");
00111   //  set_driver_hook(H_TELNET_NEG,0);
00112  
00113   // EUID und UID muessen neue Objekte auch noch kriegen, Hooks dafuer setzen
00114   set_driver_hook(H_LOAD_UIDS, #'load_uid_hook);
00115   set_driver_hook(H_CLONE_UIDS, #'clone_uid_hook);
00116 
00117   // Nun der beruechtigte Move-Hook ...
00118   // (bewegt objekt und ruft alle notwendigen inits auf)
00119   // Hier wird H_MOVE_OBJECT0 benutzt, d.h. die lambda wird an das aktuelle
00120   // Objekt vor Ausfuehrung gebunden, nicht an 'item', was move_objet()
00121   // uebergeben wurde.
00122   set_driver_hook(H_MOVE_OBJECT0,
00123      unbound_lambda(({'item,'dest}),
00124        ({#',,                                      // item!=this_object?
00125          ({#'?,({#'!=,'item,({#'this_object})}),
00126            ({#'raise_error,                        // ->Fehler!
00127              "Illegal to move other object than this_object()\n"}) }),
00128          ({#'efun::set_environment,'item,'dest}),  // item nach dest bewegen
00129          ({#'?,
00130            ({#'living,'item}),                     // living(item)?
00131            ({#',,
00132              ({#'efun::set_this_player,'item}),    // set_this_player(item)
00133              ({#'call_other,'dest,"init"}),        // dest->init()
00134              ({#'?!, 
00135                ({#'&&,                             // !objectp(item)||
00136                  ({#'objectp, 'item}),             // env(item)!=dest?
00137                  ({#'==,({#'environment, 'item}),'dest})}),
00138                ({#'return})})})}),                 // -> fertig
00139          ({#'=,'others,({#'-,({#'all_inventory,'dest}),({#'({,'item})})}),
00140 #ifdef EMACS_NERV 
00141          })   // Emacs kann ({#'({ nicht parsen    // others=all_inv(dest)-
00142 #endif                                             //        ({item})
00143          ({#'filter,'others,lambda(({'ob,'item}),
00144             ({#'?,                                     
00145               ({#'&&,
00146                 ({#'objectp,'item}),               // objectp(item)&&
00147                 ({#'living,'ob}),                  // living(ob)&&
00148                 ({#'==,({#'environment,'item}),({#'environment,'ob})})}),
00149               ({#',,                               // env(item)==env(ob)?
00150                 ({#'efun::set_this_player, 'ob}),  // set_this_player(ob)
00151                 ({#'call_other,'item, "init"})     // item->init()
00152               })})),'item}),
00153          ({#'?,
00154            ({#'living,'item}),                     // living(item)?
00155               ({#',,
00156                 ({#'efun::set_this_player,'item}), // set_this_player(item)
00157                 ({#'filter,'others,lambda(({'ob,'item}),
00158                     ({#'?,                          
00159                       ({#'&&,                 
00160                         ({#'objectp,'item}),       // objectp(item)&&
00161                         ({#'objectp,'ob}),         // objectp(ob)&&
00162                         ({#'==,({#'environment,'item}),({#'environment,'ob})})
00163                       }),                          // env(item)==env(ob)?
00164                       ({#'call_other,'ob,"init"})  // ob->init()
00165                     })),'item})})}),
00166          ({#'?,
00167            ({#'&&,
00168              ({#'objectp,'item}),                  // objectp(item)&&
00169              ({#'living,'dest}),                   // living(dest)&&
00170              ({#'==,({#'environment,'item}),'dest})// env(item)==dest?
00171            }),
00172            ({#',,
00173              ({#'efun::set_this_player,'dest}),    // set_this_player(dest)
00174              ({#'call_other,'item,"init"})})})})));// item->init()
00175   DEBUG("Master inaugurated");
00176   return;
00177 }

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

protected 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:

protected int log_error ( string  file,
string  message,
int  warn 
)

Error handling fuer Fehler beim Compilieren.

log_error() wird vom GameDriver aufgerufen, wenn zur Compile-Zeit ein Fehler auftrat. Die Fehlermeldung wird unter /log/error geloggt. Falls this_interactive() ein Magier ist, bekommt er die Fehlermeldung direkt angezeigt. Sollte das Logfile 50kB ueberschreiten, wird es rotiert. Auf [Entwicklung] wird dann eine Fehlermeldung abgesetzt.

Parameter:
file Die Datei, in der der Fehler auftrat.
message Die Fehlermeldung.
warn Warnung (warn!=0) oder Fehler (warn==0)?

Definiert in Zeile 827 der Datei master.c.

00827                                                                {
00828   string lfile;
00829   string cr;
00830   mixed *lfile_size;
00831 
00832  //Fehlerdaten an den Errord zur Speicherung weitergeben, falls wir sowas
00833  //haben.
00834 #ifdef ERRORD
00835     catch(limited(#'call_other,({200000}),ERRORD,"LogCompileProblem",
00836           file,message,warn); publish);
00837 #endif // ERRORD
00838 
00839  // Logfile bestimmen
00840   cr=creator_file(file);
00841   if (!cr)                     lfile="NOBODY.err";
00842   else if (cr==ROOTID)         lfile="ROOT";
00843   else if (member(cr,' ')!=-1) lfile="STD";
00844   else                         lfile=cr;
00845   //je nach Warnung oder Fehler Verzeichnis und Suffix bestimmen
00846   if (warn) {
00847       lfile="/log/warning/" + lfile + ".warn";
00848   }
00849   else {
00850       lfile="/log/error/" + lfile + ".err";
00851   }
00852 
00853   // Bei Bedarf Rotieren des Logfiles
00854   if ( sizeof(lfile_size = get_dir(lfile,2)) &&
00855            lfile_size[0] >= MAX_ERRLOG_SIZE )
00856   {
00857     catch(rename(lfile, lfile + ".old"); publish); /* No panic if failure */
00858     DEBUG3_MSG("Logfile rotiert: "+lfile+".");
00859   }
00860 
00861   write_file(lfile,message);
00862 
00863   // Magier bekommen die Fehlermeldung angezeigt
00864   if (IS_LEARNER(TI)) write(message);
00865   return 1;
00866 }

protected varargs void notify_shutdown ( string  crash_reason  ) 

Definiert in Zeile 594 der Datei master.c.

00594                                                              {
00595 
00596   if (PO && PO != TO)
00597     return;
00598   if (crash_reason) {
00599       //Uhoh... Verdammter Crash. :-( Zumindest mal mitloggen,
00600       //was der Driver sagt...
00601       write_file(CRASH_LOG,sprintf(
00602             "\n%s: The driver crashed! Reason: %s\n",
00603             ctime(time()),crash_reason));
00604   }
00605 
00606   filter(users(), #'tell_object,
00607                "Game driver shouts: LDmud shutting down immediately.\n");
00608   save_wiz_file();
00609   return;
00610 }

protected void preload ( string  file  ) 

Definiert in Zeile 209 der Datei master.c.

Benutzt creator_file(), err, name, TO und zeit.

00209                                     {
00210   string err;
00211   string name;
00212   int *res, zeit;
00213 
00214   // Kein richtiger Dateiname: fertig
00215   if(!file || !file[0] || file[0] == ';' || file_size(file+".c") < 0) return;
00216 
00217   // Kein Besitzer -> Meldung ausgeben, fertig
00218   if (!(name=creator_file(file)))
00219   {
00220     printf("Kein Besitzer gefunden fuer Datei %s.\n",file);
00221     return;
00222   }
00223 
00224   // Datei und Besitzer ausgeben
00225   printf("%-50s%-15s",file,name);
00226 
00227   // Euid kann nicht geaendert werden -> Meldung, fertig
00228   if (!seteuid(name))
00229   {
00230     printf("\nEuid konnte nicht auf %s gesetzt werden\n"+
00231              "Sie ist nun %s.\n",name,geteuid(TO));
00232     return;
00233   }
00234 
00235   // Dann mal laden .. dabei Zeit messen
00236   zeit = apply(#'+,rusage()[0..1]);
00237 
00238   // Waehrend des Preloads sind 1.5MTicks leider nicht soviel, insb. wenn
00239   // sowas wie der channeld jede menge Objekte laden muss, die wiederum erst
00240   // das ganze Geraffel aus /std/ laden. Daher hier einfach mal fuers Preload
00241   // die Grenze hoch.
00242   err = catch(limited(#'load_object,({5000000}),file));
00243 
00244   if (err != 0)
00245     printf("\nFehler beim Laden von %s:\n%s\n",file,err);
00246   else
00247   {
00248     zeit=apply(#'+,rusage()[0..1])-zeit;
00249     printf("(%2d.%:02d s)\n",zeit/1000,zeit%1000);
00250   }
00251 
00252   // Noch EUID zuruecksetzen
00253   seteuid(ROOTID);
00254 
00255   return;
00256 }

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

string printf_obj_name ( object  ob  ) 

Definiert in Zeile 1073 der Datei master.c.

Wird benutzt von telnet_neg().

01073 { return 0; }

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

int privilege_violation ( string  op,
mixed  who,
mixed  arg1,
mixed  arg2 
)

Definiert in Zeile 700 der Datei master.c.

00701 {
00702 
00703   if (objectp(who) && 
00704       (who==this_object() || geteuid(who)==ROOTID))
00705     return 1; 
00706 
00707   switch(op)
00708   {
00709     case "call_out_info":
00710       return -1;
00711     case "send_udp":
00712       return 1;
00713 
00714     case "nomask simul_efun":
00715     case "get_extra_wizinfo":
00716       // benutzt von /secure/memory.c und /secure/simul_efun.c
00717     case "set_extra_wizinfo":
00718       // wird benutzt von simul_efun.c, welche aber als ROOT-Objekt implizit
00719       // erlaubt ist (s.o.)
00720        if (who==SIMUL_EFUN_FILE||
00721            who == SPARE_SIMUL_EFUN_FILE)
00722          return 1;
00723        return -1;
00724 
00725     case "rename_object":
00726       if (object_name(who)=="/secure/impfetch" ||
00727           BLUE_NAME(who)=="/secure/login")
00728         return 1;
00729       return(-1);
00730 
00731     case "limited":
00732       // Spielershells duerfen sich zusaetzliche Ticks fuer den Aufruf von
00733       // ::die() beschaffen, damit der Tod nicht wegen wenig Ticks buggt.
00734       if (strstr(load_name(who), "/std/shells/") == 0
00735           && get_type_info(arg1, 2) == who
00736           && get_type_info(arg1, 3) == "/std/living/life"
00737 //          && get_type_info(arg1, 4) == "die"
00738           && arg2[LIMIT_EVAL] <= 10000000 ) {
00739           return 1;
00740       }
00741       //DEBUG(sprintf("%O, %O, %O", who, arg1, arg2));
00742       int *limits=query_limits();
00743       // LIMIT_EVAL darf verringert werden. Alle anderen Limits duerfen nicht
00744       // geaendert werden. Achja, LIMIT_EVAL darf nicht 0 (LIMIT_UNLIMITED)
00745       // sein. *g*
00746       // LIMIT_COST darf entweder 0 oder -100 sein.
00747       if (arg2[LIMIT_EVAL]>1000 && (arg2[LIMIT_EVAL] < get_eval_cost())-500
00748           && arg2[LIMIT_ARRAY] == limits[LIMIT_ARRAY]
00749           && arg2[LIMIT_MAPPING_KEYS] == limits[LIMIT_MAPPING_KEYS]
00750           && arg2[LIMIT_MAPPING_SIZE] == limits[LIMIT_MAPPING_SIZE]
00751           && arg2[LIMIT_BYTE] == limits[LIMIT_BYTE]
00752           && arg2[LIMIT_FILE] == limits[LIMIT_FILE]
00753           && arg2[LIMIT_CALLOUTS] == limits[LIMIT_CALLOUTS]
00754           && (arg2[LIMIT_COST] == 0 || arg2[LIMIT_COST] == -100) )
00755             return(1);
00756       //sonst verweigern.
00757       return(-1);
00758 
00759     case "attach_erq_demon":
00760     case "bind_lambda": 
00761     case "enable_telnet":
00762     case "execute_command":
00763     case "erq": 
00764     case "input_to":
00765     case "mysql":
00766     case "net_connect":
00767     case "pgsql":
00768     case "set_limits":
00769     case "set_extra_wizinfo_size":
00770     case "set_driver_hook":
00771     case "set_max_commands":
00772     case "set_this_object":
00773     case "shadow_add_action":
00774     case "symbol_variable":
00775     case "variable_list":
00776     case "wizlist_info":
00777     default:
00778       return(-1);
00779   }
00780   return -1;
00781 }

int query_allow_shadow ( object  ob  ) 

Definiert in Zeile 677 der Datei master.c.

00678 {
00679   // ROOT darf nicht geshadowed werden
00680   if(getuid(ob) == ROOTID)
00681     return 0;
00682   
00683   // Access-Rights auch nicht
00684   if (efun::explode(object_name(ob),"#")[0][<14..]=="/access_rights")
00685     return 0;
00686   
00687   // Ansonsten query_prevent_shadow fragen ...
00688   return !(int)ob->query_prevent_shadow(PO);
00689 }

protected void quota_demon (  ) 

Definiert in Zeile 1059 der Datei master.c.

01059                              {
01060     //was kann man machen?
01061     //uebervolle Seherhaeuser leeren? 
01062     return;
01063 }

protected void reactivate_destructed_master ( int  flag  ) 

Definiert in Zeile 1046 der Datei master.c.

01046                                                       {
01047     if (flag) {
01048         //re-init
01049         //was machen? TODO
01050     }
01051     return;
01052 }

void redo_preload (  ) 

Definiert in Zeile 286 der Datei master.c.

00287 {
00288   string *to_preload;
00289   int i,j;
00290 
00291   to_preload=epilog(0);
00292   j=sizeof(to_preload);
00293   for (i=0;i<j;i++) 
00294       catch(preload(to_preload[i]));
00295   return;
00296 }

public varargs int remove ( int  silent  ) 

Definiert in Zeile 303 der Datei master.c.

00304 {
00305   write("Der Master will aber nicht zerstoert werden!\n");
00306   return 0;
00307 }

protected void remove_player ( object  victim  ) 

Definiert in Zeile 574 der Datei master.c.

Benutzt destruct().

00575 {
00576   catch(victim->quit());
00577   if (victim) catch(victim->remove());
00578   if (victim) destruct(victim);
00579   return;
00580 }

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

protected void reset ( void   ) 

Definiert in Zeile 310 der Datei master.c.

00311 {
00312   int i, *date;
00313   mixed *wl;
00314 
00315   //Darf nicht von Hand aufgerufen werden!
00316   if (TI||TP) return;
00317   
00318   // Naechsten Reset setzen
00319   set_next_reset(RESETINT);
00320 
00321   // Userinfo aufraeumen
00322   _cleanup_uinfo();
00323 
00324   // Projekt-Cache loeschen
00325   _cleanup_projects();
00326 
00327   // Wenn Zeit abgelaufen, dann READ_FILE-Log rotieren
00328   if (!logrotate_counter--)
00329   {
00330     i=time()/LOGFILEAGE;
00331     date=get_dir(sprintf("%s.%d", READ_FILE,i%LOGNUM), GETDIR_DATES);
00332     if (pointerp(date)&&sizeof(date)&&
00333         (date[0]/LOGFILEAGE)==i) return;
00334     if (file_size(READ_FILE)>0)
00335       rename(READ_FILE, sprintf("%s.%d", READ_FILE,i%LOGNUM));
00336     logrotate_counter=LOGROTATE;
00337   }
00338   // einmal am Tag die UIDAliase resetten. Hierzu wird der logrotate_counter
00339   // missbraucht.
00340   if (!(logrotate_counter%24)) {
00341     ResetUIDAliase();
00342   }
00343 
00344   // Wizlist altert
00345   wl = wizlist_info();
00346   for (i=sizeof(wl); i--; )
00347     set_extra_wizinfo(wl[i][WL_NAME], wl[i][WL_EXTRA] * 99 / 100);
00348 
00349   // Dann noch Mails bearbeiten
00350   mails_last_hour=0;
00351   mailread();
00352 
00353   return;
00354 }

protected int retrieve_ed_setup ( object  who  ) 

Definiert in Zeile 1013 der Datei master.c.

01014 {
01015   string file;
01016 
01017   file = sprintf("/players/%s/.edrc",getuid(who));
01018   if (file_size(file)<1) return 0;
01019   return (int)read_file(file);
01020 }

protected void runtime_error ( string  err,
string  prg,
string  curobj,
int  line,
mixed  culprit,
int  caught 
)

Definiert in Zeile 942 der Datei master.c.

00943                                 {
00944 
00945     //DEBUG(sprintf("Callerstack: (runtime_error()): %O\nPO: %O\nPO(0): %O\n",
00946     //          caller_stack(1),previous_object(),previous_object(0)));
00947 
00948     limited(#'call_runtime_error, ({ LIMIT_UNLIMITED }),
00949         err,prg,curobj,line,culprit,caught,previous_object());
00950 }

protected void runtime_warning ( string  msg,
string  curobj,
string  prog,
int  line,
int  inside_catch 
)

Definiert in Zeile 953 der Datei master.c.

00954                       {
00955   string code, hashkey;
00956   string debug_txt;
00957   object titp;
00958 
00959   //DEBUG(sprintf("Callerstack: in runtime_warning(): %O\nPO(0): %O\n",
00960   //        caller_stack(1),previous_object(0)));
00961   
00962   //Daten der Warnung an den Errord zur Speicherung weitergeben, falls wir 
00963   //sowas haben.
00964 #ifdef ERRORD
00965   catch(hashkey=limited(#'call_other,({200000}),ERRORD,"LogWarning",
00966         msg,prog,curobj,line,inside_catch); publish);
00967 #endif // ERRORD
00968 
00969   // Fehlermeldung bauen
00970   if (!stringp(msg))    msg="<NULL>";
00971   if (!stringp(prog))    prog="<NULL>";
00972   if (!stringp(curobj)) curobj="<NULL>";
00973   debug_txt=sprintf("Warnung: %O, Objekt: %s, Programm: %O, Zeile %O (%s) "
00974                     "ID: %s",
00975                     msg[0..<2], curobj, (prog[0]!='<'?"/":"")+prog, line,
00976                     (TI?capitalize(getuid(TI)):"<Unbekannt>"),
00977                     hashkey||"");
00978   
00979   //Fehlermeldungen an -warnungen schicken
00980   DEBUG4_MSG(debug_txt,previous_object());
00981 
00982   titp = TI || TP;
00983 
00984   if (!titp) return;
00985   
00986   // Fehlermeldung an Benutzer
00987   if (IS_LEARNER(titp))
00988     tell_object(titp,
00989                 sprintf("%'-'78.78s\nfile: %s line: %d object: %s\n" +
00990                         "%sWarnung: %s%'-'78.78s\n","",prog,line,curobj,
00991                         (prog&&(code=read_file("/"+prog,line,1))?
00992                          "\n"+code+"\n":""),msg,""));
00993   return;
00994 }

protected int save_ed_setup ( object  who,
int  code 
)

Definiert in Zeile 1002 der Datei master.c.

01003 {
01004   string file;
01005 
01006   if (!intp(code)) return 0;
01007   file = sprintf("/players/%s/.edrc",geteuid(who));
01008   rm(file);
01009   return write_file(file,(string)code);
01010 }

protected 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:

protected void slow_shut_down ( int  minutes  ) 

Definiert in Zeile 583 der Datei master.c.

00584 {
00585   //sollte nur vom GD gerufen werden. Oder allenfalls Master selbst
00586   filter(users(),#'tell_object,
00587   "Der Gamedriver ruft: Der Speicher wird knapp ! Bereitet euch auf das Ende vor !\n");
00588   "/obj/shut"->shut(minutes);
00589   return;
00590 }

protected void stale_erq ( closure  callback  ) 

Definiert in Zeile 1040 der Datei master.c.

01040 { return; }

void telnet_neg ( mixed  cmd,
mixed  opt,
mixed  args 
)

Definiert in Zeile 1095 der Datei master.c.

Benutzt printf_obj_name().

01096 {
01097   if (opt==34 && cmd==251)
01098         binary_message(({255,250,34,1,1,255,240}));
01099 }

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

int valid_exec ( string  name,
object  ob,
object  obfrom 
)

Definiert in Zeile 620 der Datei master.c.

00621 {
00622   // Ungueltige Parameter oder Aufruf durch process_string -> Abbruch
00623   if (!objectp(ob) || !objectp(obfrom) 
00624       || !stringp(name) || !strlen(name)
00625       || funcall(symbol_function('process_call)) )
00626     return 0;
00627 
00628   // renew_player_object() darf ...
00629   if (name=="secure/master/misc.c") return 1;
00630 
00631   // Ansonsten darf sich nur die Shell selber aendern ...
00632   if (previous_object() != obfrom) return 0;
00633 
00634   // Die Login-Shell zu jedem Objekt ...
00635   if (name=="secure/login.c") return 1;
00636 
00637   // Magier per exec nur, wenn sie damit keine Fremde uid/euid bekommen
00638   if (this_interactive() == obfrom && getuid(obfrom) == getuid(ob) 
00639       && geteuid(obfrom) == geteuid(ob)) 
00640       return 1;
00641 
00642   // Sonst darf niemand was
00643   return 0;
00644 }

int valid_query_snoop ( object  wiz  ) 

Definiert in Zeile 653 der Datei master.c.

00653                                   {
00654     return getuid(PO) == ROOTID; 
00655 }

int valid_seteuid ( object  ob,
string  neweuid 
)

Definiert in Zeile 658 der Datei master.c.

00659 {
00660   return (ob==this_object() ||
00661           getuid(ob) == ROOTID ||
00662           getuid(ob) == neweuid ||
00663           creator_file(object_name(ob)) == neweuid);
00664 }

int valid_snoop ( object  me,
object  you 
)

Definiert in Zeile 648 der Datei master.c.

00648                                        { 
00649     return getuid(PO) == ROOTID; 
00650 }

int valid_trace ( string  what,
mixed  arg 
)

Definiert in Zeile 667 der Datei master.c.

00667                                         { 
00668     return IS_ARCH(TI);
00669 }


Variablen-Dokumentation

inherit secure master domain

Definiert in Zeile 21 der Datei master.c.

Wird benutzt von _addmaster(), _removemaster() und process_names().

inherit secure master file_access

Definiert in Zeile 23 der Datei master.c.

inherit secure master guild
int logrotate_counter [static]

Definiert in Zeile 45 der Datei master.c.

inherit secure master misc

Definiert in Zeile 18 der Datei master.c.

Wird benutzt von _inventory().

inherit secure master network

Definiert in Zeile 20 der Datei master.c.

inherit secure master players_deny

Definiert in Zeile 24 der Datei master.c.

inherit secure master userinfo

Definiert in Zeile 19 der Datei master.c.

Wird benutzt von finger_single().

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