#include <config.h>#include <wizlevels.h>#include <defines.h>#include <debug_info.h>#include <commands.h>#include <mail.h>#include "errord.h"

gehe zum Quellcode dieser Datei
Makrodefinitionen | |
| #define | __NEED_IMPLEMENTATION__ |
| #define | SAVEFILE (__DIR__+"ARCH/errord") |
| #define | TI this_interactive() |
Funktionen | |
| string | LogError (string msg, string prg, string curobj, int line, mixed culprit, int caught) |
| string | LogWarning (string msg, string prg, string curobj, int line, int in_catch) |
| string | LogCompileProblem (string file, string msg, int warn) |
| mapping | QueryLastError (int type) |
| varargs mapping | QueryError (string hashkey, int type, string uid) |
| mapping | QueryErrors (int type, string uid) |
| varargs string * | QueryErrorIDs (int type, string uid) |
| varargs string * | QueryUIDsForType (int type) |
| varargs int | QueryUniqueErrorNo (int type, string uid) |
| varargs int | QueryErrorNo (int type, string uid) |
| varargs int | ToggleDeleteError (string hashkey, string note, int type, string uid) |
| varargs mixed | LockError (string hashkey, string note, int type, string uid) |
| varargs int | UnlockError (string hashkey, string note, int type, string uid) |
| varargs int | ResolveError (string hashkey, string note, int type, string uid) |
| varargs int | ReOpenError (string hashkey, string note, int type, string uid) |
| varargs int | AddNote (string hashkey, string note, int type, string uid) |
| varargs int | ReassignError (string hashkey, string newuid, string note, int type, string uid) |
| public string | find_uid_for_hash (string hashkey, int type) |
| public mixed | find_global_hash (string hashkey) |
| mixed | QueryAll (int type) |
| mixed | QueryResolved () |
| void | create () |
| string | name () |
| void | save_me () |
| varargs int | remove (int silent) |
| private varargs void | _expire_empty_uids (int *types, string *uids) |
| private varargs void | _expire (int zeit, int *types, string *uids, string *hashes) |
| private varargs mixed | set_lock (string hashkey, int lock, string note, int type, string uid) |
| private varargs mapping | getError (string hashkey, int type, string uid) |
| private varargs int | set_resolution (string hashkey, int res, string note, int type, string uid) |
| private int | queryUniqueErrorNoForUID (int type, string uid) |
| private int | queryErrorNoForUID (int type, string uid) |
| private int | access_check (string uid, int mode) |
| private mapping | filter_private (string hashkey, mapping error) |
| public string | format_stacktrace (mixed bt) |
| public string | format_notes (mixed notes) |
| public string | format_error (string hashvalue, mapping fehler) |
| private int | versende_mail (mapping fehler) |
| private void | archive () |
| void | reset () |
| public string | NotifyDestruct (object caller) |
Variablen | |
| mapping | errors |
| mapping | resolved |
| nosave mapping | lasterror |
| private varargs void _expire | ( | int | zeit, | |
| int * | types, | |||
| string * | uids, | |||
| string * | hashes | |||
| ) |
Definiert in Zeile 752 der Datei errord.c.
00753 { 00754 //in den Arrays steht das aktuell bearbeitete immer ganze vorne drin, das 00755 //wird auch erst geloescht, wenn ich damit fertig bin. 00756 int i,size; 00757 mapping mapp; 00758 00759 //DEBUG("_expire gerufen.\n"); 00760 00761 //ohne vernuenftige Zeitangabe wird nix gemacht. 00762 if (!intp(zeit) || zeit<=0) 00763 return; 00764 00765 //wenn keine types: alle types holen 00766 if (!pointerp(types)) 00767 types=m_indices(errors); 00768 //DEBUG(sprintf("Types: %O\n",types)); 00769 00770 //mapping fuer den aktuellen Typ holen 00771 if (!sizeof(types)) return; 00772 mapp=errors[types[0]]; 00773 00774 //alle UIDs des aktuellen Typs holen 00775 if (!pointerp(uids)) 00776 uids=m_indices(mapp); 00777 //DEBUG(sprintf("UIDs: %O\n",uids)); 00778 //wenn keine UIDs in dem Mapping sind: mit naechstem Typ weitermachen 00779 if (!sizeof(uids)) { 00780 if (sizeof(types)>1) //ok, noch was uebrig zu bearbeiten 00781 call_out(#'_expire,2,zeit,types[1..]); 00782 00783 return; 00784 } 00785 00786 //alle Hashes der aktueller UID holen 00787 if (!pointerp(hashes)) 00788 hashes=m_indices(mapp[uids[0]]); 00789 //Pruefung, ob es Eintraege unter dieser UID gibt, sind nicht noetig, ist 00790 //in der while-Schleife drin. 00791 00792 size=sizeof(hashes); 00793 while(i<size && get_eval_cost()>750000) { 00794 // Fehlereintrag loeschen, wenn nicht gelockt und letzte Aenderung 00795 // zu lang her war oder wenn als geloescht markiert. 00796 if ( (mapp[uids[0]][hashes[i]][F_MODSTAMP]<zeit && 00797 !(mapp[uids[0]][hashes[i]][F_STATE] & STAT_LOCKED) ) || 00798 mapp[uids[0]][hashes[i]][F_STATE] & STAT_DELETED) { 00799 efun::m_delete(mapp[uids[0]],hashes[i]); 00800 //DEBUG(sprintf("_expire: Eintrag %s aus UID %s geloescht.\n", 00801 // hashes[i], uids[0])); 00802 } 00803 i++; 00804 } 00805 00806 if (i<size) { 00807 hashes=hashes[i..]; //rest mitnehmen in den naechsten Durchlauf 00808 call_out(#'_expire,2,zeit,types,uids,hashes); 00809 //DEBUG(sprintf("Callout auf _expire() mit Types %O " 00810 // "und UIDs: %O und Hashes: %O gestartet.\n",types,uids,hashes)); 00811 } 00812 else if (sizeof(uids)>1) { 00813 uids=uids[1..]; //rest mitnehmen in den naechsten Durchlauf 00814 //lfun closure wegen private 00815 call_out(#'_expire,2,zeit,types,uids); 00816 //DEBUG(sprintf("Callout auf _expire() mit Types %O " 00817 // "und UIDs: %O gestartet.\n",types,uids)); 00818 } 00819 else if (sizeof(types)>1) {//wenn noch mehr als einer hier drinsteht, 00820 types=types[1..]; //in den naechsten Durchlauf mitnehmen. 00821 //lfun closure wegen private 00822 call_out(#'_expire,2,zeit, types); 00823 //DEBUG(sprintf("Callout auf _expire mit Types: %O " 00824 // "gestartet.\n",types)); 00825 } 00826 else { 00827 //scheinbar ist nix mehr weiter zu tun, also mal leere UIDs loswerden. 00828 call_out(#'_expire_empty_uids,10); 00829 //DEBUG(sprintf("Callout auf _expire_empty_uids gestartet.\n")); 00830 } 00831 return; 00832 }
| private varargs void _expire_empty_uids | ( | int * | types, | |
| string * | uids | |||
| ) |
Definiert in Zeile 711 der Datei errord.c.
00711 { 00712 int i,size; 00713 mapping mapp; 00714 00715 if (!pointerp(types)) 00716 types=m_indices(errors); 00717 00718 if (!sizeof(types)) return; 00719 mapp=errors[types[0]]; 00720 00721 if (!pointerp(uids)) 00722 uids=m_indices(mapp); 00723 00724 size=sizeof(uids); 00725 while(i<size && get_eval_cost()>750000) { 00726 if (!sizeof(mapp[uids[i]])) { 00727 efun::m_delete(mapp,uids[i]); 00728 //DEBUG(sprintf("_expire_empty_uids: Leere UID %s geloescht.\n", 00729 // uids[i])); 00730 } 00731 i++; 00732 } 00733 00734 if (i<size) { 00735 uids=uids[i..]; //rest mitnehmen in den naechsten Durchlauf 00736 //lfun closure wegen private 00737 call_out(#'_expire_empty_uids,10,types,uids); 00738 //DEBUG(sprintf("Callout auf _expire_empty_uids() mit Types %O " 00739 // "und UIDs: %O gestartet.\n",types,uids)); 00740 } 00741 else if (sizeof(types)>1) {//wenn noch mehr als einer hier drinsteht, 00742 types=types[1..]; //in den naechsten Durchlauf mitnehmen. 00743 //lfun closure wegen private 00744 call_out(#'_expire_empty_uids,10,types); 00745 //DEBUG(sprintf("Callout auf _expire_empty_uids() mit Types: %O " 00746 // "gestartet.\n",types)); 00747 } 00748 return; 00749 }
| private int access_check | ( | string | uid, | |
| int | mode | |||
| ) |
Definiert in Zeile 997 der Datei errord.c.
Benutzt ARCH_SECURITY, master, process_call(), QueryUIDsForWizard() und secure_euid().
00997 { 00998 00999 if (mode==M_READ) 01000 return(1); //lesen darf jeder 01001 01002 // In process_string() schonmal gar nicht. 01003 if (process_call()) return(0); 01004 // EM+ duerfen alles loeschen. 01005 if (ARCH_SECURITY) return(1); 01006 // eigene UIDs darf man auch bearbeiten. 01007 if (secure_euid()==uid) return(1); 01008 01009 // Master nach UIDs fragen, fuer die der jew. Magier 01010 // zustaendig ist. 01011 if (member((string *)master()->QueryUIDsForWizard(secure_euid()),uid)) 01012 return(1); 01013 01014 return(0); //Fall-through, nein 01015 }

| varargs int AddNote | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 533 der Datei errord.c.
Benutzt err, getError(), resolved, save_me() und TI.
00533 { 00534 mapping err; 00535 00536 if (member(resolved,hashkey)) 00537 err=resolved[hashkey]; 00538 else 00539 err=getError(hashkey,type,uid); 00540 if (!mappingp(err)) 00541 return(-1); 00542 00543 // absichtlich kein Access-Check, weil ja auch Magier, die nicht 00544 // zustaendig sind und keine Schreibrechte haben, ne gute Idee oder nen 00545 // Hinweis zu nem Bug haben koennen. 00546 // Wenn jemand spammt... Naja, social problem. ;-) 00547 /*if (!access_check(err[F_UID], M_WRITE)) 00548 //zugriff zum Schreiben nicht gestattet 00549 return(-2); 00550 */ 00551 00552 if (!stringp(note) || !strlen(note)) 00553 return(-3); 00554 00555 if (!pointerp(err[F_NOTES])) 00556 err[F_NOTES]=({}); 00557 err[F_NOTES]+=({ ({time(),getuid(TI),note}) }); 00558 save_me(); 00559 return(1); 00560 }

| private void archive | ( | ) |
Definiert in Zeile 1192 der Datei errord.c.
Benutzt call_out() und resolved.
Wird benutzt von reset().
01192 { 01193 string txt=""; 01194 if (!sizeof(resolved)) { 01195 call_out(#'_expire,2,time()-STDEXPIRE); 01196 return; 01197 } 01198 foreach(string hashkey, mapping fehler: resolved) { 01199 if (get_eval_cost() < __MAX_EVAL_COST__/2) 01200 break; // abbrechen. ;-) 01201 txt+=format_error(hashkey,fehler)+"\n"; 01202 efun::m_delete(resolved,hashkey); 01203 } 01204 write_file(CHANGELOG,txt); 01205 call_out(#'archive,4); 01206 }


| void create | ( | ) |
Definiert in Zeile 676 der Datei errord.c.
00676 { 00677 seteuid(getuid(ME)); 00678 if (!restore_object(SAVEFILE)) { 00679 errors=([T_RTERROR: ([]), 00680 T_RTWARN: ([]), 00681 T_CTERROR: ([]), 00682 T_CTWARN: ([]) ]); 00683 resolved=([]); 00684 } 00685 if (!mappingp(errors)) 00686 errors=([T_RTERROR: ([]), 00687 T_RTWARN: ([]), 00688 T_CTERROR: ([]), 00689 T_CTWARN: ([]) ]); 00690 if (!mappingp(resolved)) 00691 resolved=([]); 00692 00693 lasterror=([]); 00694 }
| private mapping filter_private | ( | string | hashkey, | |
| mapping | error | |||
| ) |
Definiert in Zeile 1017 der Datei errord.c.
Benutzt ARCH_SECURITY, F_CLI und process_call().
Wird benutzt von QueryError().
01017 { 01018 mapping errcopy; 01019 //liefert eine (gefilterte) Kopie des Fehlereintrags, momentan wird F_CLI, 01020 //also die Spielereingabe vor dem Fehler ausgefiltert, wenn TI kein EM 01021 //oder man in process_string() ist. 01022 01023 if (!stringp(hashkey) || !mappingp(error)) 01024 return(([])); 01025 01026 errcopy=deep_copy(error); 01027 //Wenn EM und nicht in process_string() oder die Spielereingabe gar nicht 01028 //im Fehlereintrag drinsteht: ungefiltert zurueck 01029 if (errcopy[F_CLI]==0 || 01030 (!process_call() && ARCH_SECURITY) ) 01031 return(errcopy); 01032 01033 //sonst F_CLI rausfiltern, also Kopie und in der Kopie aendern. 01034 errcopy[F_CLI]="Bitte EM fragen"; 01035 return(errcopy); 01036 }


| public mixed find_global_hash | ( | string | hashkey | ) |
Definiert in Zeile 621 der Datei errord.c.
00621 { 00622 //sucht in allen Fehlermappings einen Eintrag mit dem Key hash 00623 //liefert Array mit Typ und UID zurueck, wenn gefunden, sonst leeres Array 00624 // ACHTUNG: potentiell sehr teuer! 00625 mapping mapp; 00626 int i; 00627 string uid; 00628 //ueber alle Typen iterieren 00629 foreach(int type: m_indices(errors)) { 00630 if (strlen(uid=find_uid_for_hash(hashkey,type))) 00631 return(({type,uid})); 00632 } 00633 return(({})); //not found 00634 }
| public string find_uid_for_hash | ( | string | hashkey, | |
| int | type | |||
| ) |
| public string format_error | ( | string | hashvalue, | |
| mapping | fehler | |||
| ) |
Definiert in Zeile 1070 der Datei errord.c.
Benutzt abs, ARCH_SECURITY, break_string(), BS_INDENT_ONCE, dtime(), F_CAUGHT, F_CLI, F_COUNT, F_CREATESTAMP, F_HB_OBJ, F_LINE, F_LOADNAME, F_MODSTAMP, F_MSG, F_OBJ, F_PROG, F_STACK, F_TIENV, F_TITP, F_VERB, format_notes(), format_stacktrace(), process_call(), T_RTERROR und T_RTWARN.
01070 { 01071 string txt; 01072 string *label; 01073 01074 if (!mappingp(fehler) || !sizeof(fehler) || !strlen(hashvalue)) { 01075 return 0; 01076 } 01077 switch(fehler[F_TYPE]) { 01078 case T_RTERROR: 01079 label=({"Fehler","Dieser Fehler"}); 01080 break; 01081 case T_RTWARN: 01082 label=({"Warnung","Diese Warnung"}); 01083 break; 01084 default: return 0; 01085 } 01086 01087 txt=sprintf( "Daten fuer %s mit ID '%s':\n" 01088 "Zeit: %25s (Erstmalig: %25s)\n" 01089 "Programm: %.60s\n" 01090 "Zeile: %.60d\n" 01091 "Objekt: %.60s\n" 01092 "Loadname: %.60s\n" 01093 "UID: %.60s\n", 01094 label[0], hashvalue, 01095 dtime(abs(fehler[F_MODSTAMP])),dtime(fehler[F_CREATESTAMP]), 01096 fehler[F_PROG], fehler[F_LINE], fehler[F_OBJ], 01097 fehler[F_LOADNAME], fehler[F_UID]); 01098 01099 txt+=sprintf("%s",break_string(fehler[F_MSG],78, 01100 "Meldung: ",BS_INDENT_ONCE)); 01101 if (stringp(fehler[F_HB_OBJ])) 01102 txt+=sprintf( 01103 "HB-Obj: %.60s\n",fehler[F_HB_OBJ]); 01104 01105 if (stringp(fehler[F_TITP])) { 01106 txt+=sprintf( 01107 "TI/TP: %.60s\n",fehler[F_TITP]); 01108 if (stringp(fehler[F_TIENV])) 01109 txt+=sprintf( 01110 "Environm.: %.60s\n",fehler[F_TIENV]); 01111 } 01112 01113 if (!stringp(fehler[F_CLI]) || 01114 !ARCH_SECURITY || process_call()) { 01115 // Kommandoeingabe ist Privatsphaere und darf nicht von jedem einsehbar 01116 // sein. 01117 // in diesem Fall aber zumindest das Verb ausgeben, so vorhanden 01118 if (fehler[F_VERB]) 01119 txt+=sprintf( 01120 "Verb: %.60s\n",fehler[F_VERB]); 01121 } 01122 // !process_call() && ARCH_SECURITY erfuellt... 01123 else if (stringp(fehler[F_CLI])) 01124 txt+=sprintf( 01125 "Befehl: %.60s\n",fehler[F_CLI]); 01126 01127 if (fehler[F_CAUGHT]) 01128 txt+=label[1]+" trat in einem 'catch()' auf.\n"; 01129 /* // Diese Infos interessieren im Changelog nicht. 01130 if (fehler[F_STATE] & STAT_DELETED) 01131 txt+=label[1]+" wurde als geloescht markiert.\n"; 01132 01133 if (fehler[F_STATE] & STAT_LOCKED) 01134 txt+=break_string( 01135 sprintf("%s wurde von %s am %s vor automatischem Loeschen " 01136 "geschuetzt (locked).\n", 01137 label[1],fehler[F_LOCK][1],dtime(fehler[F_LOCK][0])),78); 01138 if (fehler[F_STATE] & STAT_RESOLVED) 01139 txt+=label[1]+" wurde als erledigt markiert.\n"; 01140 */ 01141 txt+=sprintf("%s trat bisher %d Mal auf.\n", 01142 label[1],fehler[F_COUNT]); 01143 01144 if (pointerp(fehler[F_STACK])) 01145 txt+="Backtrace:\n"+format_stacktrace(fehler[F_STACK])+"\n"; 01146 01147 if (pointerp(fehler[F_NOTES]) && sizeof(fehler[F_NOTES])) 01148 txt+="Bemerkungen:\n"+format_notes(fehler[F_NOTES])+"\n"; 01149 01150 return txt; 01151 }

| public string format_notes | ( | mixed | notes | ) |
Definiert in Zeile 1059 der Datei errord.c.
Benutzt break_string(), dtime() und i.
01059 { 01060 int i; 01061 string txt=""; 01062 foreach(mixed note: notes) { 01063 txt+=sprintf("Notiz %d von %.10s am %.30s\n%s", 01064 ++i,capitalize(note[1]),dtime(note[0]), 01065 break_string(note[2],78," ")); 01066 } 01067 return txt; 01068 }

| public string format_stacktrace | ( | mixed | bt | ) |
Definiert in Zeile 1038 der Datei errord.c.
Benutzt lines, TRACE_LOC, TRACE_NAME, TRACE_OBJECT und TRACE_PROGRAM.
01038 { 01039 string *lines; 01040 01041 if (!pointerp(bt) || !sizeof(bt)) 01042 return(""); 01043 lines=({}); 01044 foreach(mixed frame: bt) { 01045 if (stringp(frame)) 01046 lines+=({sprintf("Thread-Start: %s",frame)}); 01047 else if (pointerp(frame)) { 01048 lines+=({sprintf("Fun: %.20O in Prog: %.40s\n" 01049 " Zeile: %.8d [%.50s]", 01050 frame[TRACE_NAME],frame[TRACE_PROGRAM], 01051 frame[TRACE_LOC],frame[TRACE_OBJECT]) 01052 }); 01053 } 01054 } 01055 01056 return(implode(lines,"\n")); 01057 }
| private varargs mapping getError | ( | string | hashkey, | |
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 887 der Datei errord.c.
Wird benutzt von AddNote(), LogCompileProblem(), LogError(), LogWarning(), QueryError(), ReassignError() und set_lock().
00887 { 00888 mapping err; 00889 mixed arr; 00890 00891 if (!stringp(hashkey) || !strlen(hashkey)) return(0); 00892 if (!stringp(uid) && !type) { 00893 arr=find_global_hash(hashkey); 00894 if (sizeof(arr)==2) { 00895 type=arr[0]; 00896 uid=arr[1]; 00897 } 00898 else return 0; 00899 } 00900 else if (!stringp(uid)) { 00901 if (!strlen(uid=find_uid_for_hash(hashkey,type))) 00902 return 0; 00903 } 00904 if (!member(errors[type],uid) || 00905 !member(errors[type][uid],hashkey)) 00906 return 0; 00907 00908 if (mappingp(err=errors[type][uid][hashkey])) { 00909 return(err); 00910 } 00911 00912 return 0; 00913 }

| varargs mixed LockError | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 516 der Datei errord.c.
Benutzt set_lock().
00516 { 00517 return set_lock(hashkey, 1, note, type, uid); 00518 }

| string LogCompileProblem | ( | string | file, | |
| string | msg, | |||
| int | warn | |||
| ) |
Definiert in Zeile 289 der Datei errord.c.
Benutzt call_out(), err, errors, F_COUNT, F_CREATESTAMP, F_HASHKEY, F_LOADNAME, F_MODSTAMP, F_MSG, F_STATE, F_TYPE, F_UID, getError(), lasterror, m_delete(), master, STAT_DELETED, T_CTERROR und T_CTWARN.
00289 { 00290 string uid,hashkey; 00291 mapping mapp, err; 00292 00293 //DEBUG(sprintf("LogCompileProblem: Prog: %O, Obj: %O,\n",file,msg)); 00294 00295 //darf nur vom Master gerufen werden 00296 if (!extern_call() || 00297 (previous_object() && previous_object() != master())) 00298 return 0; 00299 00300 //loggen wir fuer das File ueberhaupt? 00301 if (member(BLACKLIST,explode(file,"/")[<1])>=0) 00302 return 0; 00303 00304 //UID bestimmen 00305 uid=(string)master()->creator_file(file); 00306 //DEBUG(sprintf("LogCompileProblem UID: %s\n",uid)); 00307 00308 //Hashkey bestimmen, in diesem Fall einfach, wir koennen die 00309 //Fehlermeldunge selber nehmen. 00310 hashkey=md5(msg); 00311 //DEBUG(sprintf("LogCompileProblem: Hashkey: %s",hashkey)); 00312 00313 // ggf. vorhandene Warnung suchen. Dieser muss leider in allen UIDs 00314 // gesucht werden. Falls eine Warnung von ihrer urspruenglichen in eine 00315 // neue UID verschoben wurde, wuerde es sonst ggf. 2 Warnungen mit dem 00316 // gleichen hashkey in verschiedenen UIDs geben. 00317 // ausserdem das richtige Mapping finden. 00318 if (warn) { 00319 err = getError(hashkey, T_CTWARN); 00320 mapp=errors[T_CTWARN]; 00321 } 00322 else { 00323 err = getError(hashkey, T_CTERROR); 00324 mapp=errors[T_CTERROR]; 00325 } 00326 00327 // schonmal speichern anstossen 00328 if (find_call_out("save_me")==-1) 00329 //Zeitverzoegert, falls viele Fehler direkt hintereinander kommen. 00330 call_out("save_me",10); 00331 00332 if (mappingp(err) && sizeof(err)) { 00333 //wenn dieser hashkey / Fehler schon drin ist im Mapping und nicht 00334 //als geloescht markiert, zaehlen wir nur den Counter hoch und 00335 //aktualisieren den Zeitstempel, sonst loeschen. 00336 if (err[F_STATE] & STAT_DELETED) 00337 efun::m_delete(mapp[err[F_UID]], hashkey); 00338 else { 00339 err[F_COUNT]++; 00340 err[F_MODSTAMP]=time(); 00341 return hashkey; // und fertig 00342 } 00343 } 00344 // neuen Eintrag 00345 if (!member(mapp,uid)) mapp+=([uid:([])]); 00346 if (!mappingp(mapp[uid])) mapp[uid]=([]); 00347 err=([F_TYPE: (warn ? T_CTWARN : T_CTERROR), 00348 F_MODSTAMP: time(), 00349 F_CREATESTAMP: time(), 00350 F_LOADNAME: file, 00351 F_MSG: msg, 00352 F_COUNT: 1, 00353 F_UID: uid, 00354 F_HASHKEY: hashkey, 00355 ]); 00356 mapp[uid][hashkey]=err; 00357 00358 if (warn) lasterror[T_CTWARN]=hashkey; 00359 else lasterror[T_CTERROR]=hashkey; 00360 00361 // DEBUG(sprintf("LogCompileProblem: Eintrag:\n%O\n", 00362 // (warn ? ctwarnings[uid][hashkey] : cterrors[uid][hashkey]))); 00363 // DEBUG(sprintf("LogCompileProblem: Verbrauchte Ticks: %d\n", 00364 // 200000-get_eval_cost())); 00365 return(hashkey); 00366 }

| string LogError | ( | string | msg, | |
| string | prg, | |||
| string | curobj, | |||
| int | line, | |||
| mixed | culprit, | |||
| int | caught | |||
| ) |
Definiert in Zeile 40 der Datei errord.c.
Benutzt call_out(), CMD_TEXT, CMD_VERB, DEBUG, debug_info(), DINFO_TRACE, DIT_ERROR, DIT_UNCAUGHT_ERROR, err, errors, F_CAUGHT, F_CLI, F_COUNT, F_CREATESTAMP, F_HASHKEY, F_HB_OBJ, F_LINE, F_LOADNAME, F_MODSTAMP, F_MSG, F_OBJ, F_PROG, F_STACK, F_STATE, F_TIENV, F_TITP, F_TYPE, F_UID, F_VERB, getError(), lasterror, m_delete(), master, PL, STAT_DELETED und T_RTERROR.
00041 { 00042 mixed stacktrace, cli, tienv; 00043 string uid, hashkey, loadname, titp, cverb; 00044 mapping errs, err; 00045 //DEBUG(sprintf("LogError: Prog: %O, Obj: %O,\n",prg,curobj)); 00046 00047 //darf nur vom Master gerufen werden 00048 if (!extern_call() || 00049 (previous_object() && previous_object() != master())) 00050 return 0; 00051 00052 //UID bestimmen 00053 uid=(string)master()->creator_file(curobj); 00054 //DEBUG(sprintf("LogError: UID: %s\n",uid)); 00055 00056 //Loadname (besser als BP, falls rename_object() benutzt wurde) bestimmen 00057 if (!stringp(curobj) || !strlen(curobj)) 00058 loadname = curobj = "<Unbekannt>"; 00059 else 00060 //load_name nimmt Strings und Objects und konstruiert den loadname, 00061 //wie er sein sollte, wenn das Objekt nicht mehr existiert. 00062 loadname=load_name(curobj); 00063 00064 if (!stringp(loadname) || !strlen(loadname)) 00065 //hier sollte man reinkommen, falls curobj ein 'kaputter' Name ist. 00066 loadname="<Illegal object name>"; 00067 00068 //Hashkey bestimmen, testweise Name der Blueprint des buggenden Objekts 00069 //+ Zeilennr. 00070 //TODO: evtl. sha1() statt md5()? 00071 hashkey=md5(sprintf("%s%d",loadname,line)); 00072 DEBUG(sprintf("LogError: Hashkey: %s",hashkey)); 00073 00074 // schonmal Speichern anstossen 00075 if (find_call_out("save_me")==-1) 00076 //Zeitverzoegert, falls viele Fehler direkt hintereinander kommen. 00077 call_out("save_me",10); 00078 00079 // ggf. vorhandenen Fehler suchen. Dieser muss leider in allen UIDs 00080 // gesucht werden. Falls ein Fehler von seiner urspruenglichen in eine 00081 // neue UID verschoben wurde, wuerde es sonst ggf. 2 Fehler mit dem 00082 // gleichen hashkey in verschiedenen UIDs geben. 00083 err = getError(hashkey, T_RTERROR); 00084 errs = errors[T_RTERROR]; 00085 if (!member(errs,uid)) errs+=([uid:([])]); 00086 if (!mappingp(errs[uid])) errs[uid]=([]); 00087 00088 if (mappingp(err) && sizeof(err)) { 00089 //wenn dieser Hashkey / Fehler schon drin ist im Mapping und nicht als 00090 //geloescht markiert, zaehlen wir nur den Counter hoch und 00091 //aktualisieren den Zeitstempel, sonst wird komplett geloescht. 00092 if (err[F_STATE] & STAT_DELETED) 00093 efun::m_delete(errs[err[F_UID]],hashkey); 00094 else { 00095 err[F_COUNT]++; 00096 err[F_MODSTAMP]=time(); 00097 return hashkey; // und fertig 00098 } 00099 } 00100 //sonst fuegen wir einen neuen Eintrag hinzu 00101 //DEBUG(sprintf("LogError: OBJ: %s, BP: %s",curobj,loadname)); 00102 // Wenn Fehler im HB, Objektnamen ermitteln 00103 if (objectp(culprit)) 00104 culprit=object_name(culprit); 00105 else culprit=0; 00106 //stacktrace holen 00107 if (caught) 00108 stacktrace=debug_info(DINFO_TRACE,DIT_ERROR); 00109 else 00110 stacktrace=debug_info(DINFO_TRACE,DIT_UNCAUGHT_ERROR); 00111 //gibt es einen TI/TP? Name mit erfassen 00112 if(objectp(this_interactive())) { 00113 titp=getuid(this_interactive()); 00114 tienv=environment(this_interactive()); 00115 } 00116 else if (objectp(PL) && query_once_interactive(PL)) { 00117 titp=getuid(PL); 00118 tienv=environment(PL); 00119 } 00120 else if (objectp(PL)) { 00121 titp=object_name(PL); 00122 tienv=environment(PL); 00123 } 00124 else 00125 titp=""; 00126 if (objectp(tienv)) tienv=object_name(tienv); 00127 00128 // Mal schauen, ob der Commandstack auch was fuer uns hat. ;-) 00129 if (pointerp(cli=command_stack()) && sizeof(cli)) { 00130 cverb=cli[0][CMD_VERB]; 00131 cli=cli[0][CMD_TEXT]; 00132 } 00133 else cli=0; //nicht unwichtig, sonst u.U. Array! ;-) 00134 00135 err=([F_TYPE: T_RTERROR, 00136 F_MODSTAMP: time(), 00137 F_CREATESTAMP: time(), 00138 F_PROG: prg, 00139 F_OBJ: curobj, 00140 F_LOADNAME: loadname, 00141 F_LINE: line, 00142 F_MSG: msg, 00143 F_HB_OBJ: culprit, 00144 F_CAUGHT: caught, 00145 F_TITP: titp, 00146 F_STACK: stacktrace, 00147 F_CLI: (string)cli, 00148 F_VERB: cverb, 00149 F_COUNT: 1, 00150 F_TIENV: (string)tienv, 00151 F_UID: uid, 00152 F_HASHKEY: hashkey, 00153 ]); 00154 // Keys ohne Werte ausfiltern 00155 foreach(string key, mixed val: err) { 00156 if (!val) efun::m_delete(err,key); 00157 } 00158 errs[uid][hashkey]=err; 00159 00160 lasterror[T_RTERROR]=hashkey; 00161 // DEBUG(sprintf("LogError: Fehlereintrag:\n%O\n", 00162 // errors[uid][hashkey])); 00163 // DEBUG(sprintf("LogError: Verbrauchte Ticks: %d\n", 00164 // 200000-get_eval_cost())); 00165 return(hashkey); 00166 }

| string LogWarning | ( | string | msg, | |
| string | prg, | |||
| string | curobj, | |||
| int | line, | |||
| int | in_catch | |||
| ) |
Definiert in Zeile 171 der Datei errord.c.
Benutzt call_out(), CMD_TEXT, CMD_VERB, err, errors, F_CAUGHT, F_CLI, F_COUNT, F_CREATESTAMP, F_HASHKEY, F_LINE, F_LOADNAME, F_MODSTAMP, F_MSG, F_OBJ, F_PROG, F_STATE, F_TIENV, F_TITP, F_TYPE, F_UID, F_VERB, getError(), lasterror, m_delete(), master, PL, STAT_DELETED und T_RTWARN.
00171 { 00172 string uid,hashkey,loadname,titp, cverb; 00173 mixed tienv, cli; 00174 00175 //DEBUG(sprintf("LogWarning: Prog: %O, Obj: %O,\n",prg,curobj)); 00176 00177 //darf nur vom Master gerufen werden 00178 if (!extern_call() || 00179 (previous_object() && previous_object() != master())) 00180 return 0; 00181 00182 //UID bestimmen 00183 uid=(string)master()->creator_file(curobj); 00184 //DEBUG(sprintf("LogWarning UID: %s\n",uid)); 00185 00186 //Loadname (besser als BP, falls rename_object() benutzt wurde) bestimmen 00187 if (!stringp(curobj) || !strlen(curobj)) 00188 loadname = curobj = "<Unbekannt>"; 00189 else 00190 //load_name nimmt Strings und Objects und konstruiert den loadname, 00191 //wie er sein sollte, wenn das Objekt nicht mehr existiert. 00192 loadname=load_name(curobj); 00193 00194 if (!stringp(loadname) || !strlen(loadname)) 00195 //hier sollte man reinkommen, falls curobj ein 'kaputter' Name ist. 00196 loadname="<Illegal object name>"; 00197 00198 //DEBUG(sprintf("LogWarning: OBJ: %s, BP: %s\n",curobj,blue)); 00199 00200 //Hashkey bestimmen, testweise Name der Blueprint des buggenden Objekts 00201 //+ Zeilennr. 00202 hashkey=md5(sprintf("%s%d",loadname,line)); 00203 //DEBUG(sprintf("LogWarning: Hashkey: %s",hashkey)); 00204 00205 // schonmal Speichern anstossen 00206 if (find_call_out("save_me")==-1) 00207 //Zeitverzoegert, falls viele Fehler direkt hintereinander kommen. 00208 call_out("save_me",10); 00209 00210 // ggf. vorhandene Warnung suchen. Dieser muss leider in allen UIDs 00211 // gesucht werden. Falls eine Warnung von ihrer urspruenglichen in eine 00212 // neue UID verschoben wurde, wuerde es sonst ggf. 2 Warnungen mit dem 00213 // gleichen hashkey in verschiedenen UIDs geben. 00214 mapping err = getError(hashkey, T_RTWARN); 00215 mapping warnings=errors[T_RTWARN]; 00216 if (!member(warnings,uid)) warnings+=([uid:([])]); 00217 if (!mappingp(warnings[uid])) warnings[uid]=([]); 00218 00219 if (mappingp(err) && sizeof(err)) { 00220 //wenn dieser Hashkey / Fehler schon drin ist im Mapping und nicht als 00221 //geloescht markiert, zaehlen wir nur den Counter hoch und 00222 //aktualisieren den Zeitstempel, sonst erstmal komplett loeschen. 00223 if (err[F_STATE] & STAT_DELETED) 00224 efun::m_delete(warnings[err[F_UID]],hashkey); 00225 else { 00226 err[F_COUNT]++; 00227 err[F_MODSTAMP]=time(); 00228 return hashkey; // und fertig. 00229 } 00230 } 00231 //sonst fuegen wir einen neuen Eintrag hinzu 00232 //gibt es einen TI/TP? Name mit erfassen 00233 if(objectp(this_interactive())) { 00234 titp=getuid(this_interactive()); 00235 tienv=environment(this_interactive()); 00236 } 00237 else if (objectp(PL) && query_once_interactive(PL)) { 00238 titp=getuid(PL); 00239 tienv=environment(PL); 00240 } 00241 else if (objectp(PL)) { 00242 titp=object_name(PL); 00243 tienv=environment(PL); 00244 } 00245 else 00246 titp=""; 00247 if (objectp(tienv)) tienv=object_name(tienv); 00248 // Mal schauen, ob der Commandstack auch was fuer uns hat. ;-) 00249 if (pointerp(cli=command_stack()) && sizeof(cli)) { 00250 cverb=cli[0][CMD_VERB]; 00251 cli=cli[0][CMD_TEXT]; 00252 } 00253 else cli=0; //nicht unwichtig, sonst u.U. Array! ;-) 00254 00255 err=([F_TYPE: T_RTWARN, 00256 F_MODSTAMP: time(), 00257 F_CREATESTAMP: time(), 00258 F_PROG: prg, 00259 F_OBJ: curobj, 00260 F_LOADNAME: loadname, 00261 F_LINE: line, 00262 F_MSG: msg, 00263 F_CAUGHT: in_catch, 00264 F_TITP: titp, 00265 F_CLI: (string)cli, 00266 F_VERB: cverb, 00267 F_COUNT: 1, 00268 F_TIENV: (string)tienv, 00269 F_UID: uid, 00270 F_HASHKEY: hashkey, 00271 ]); 00272 // Keys ohne Werte ausfiltern 00273 foreach(string key, mixed val: err) { 00274 if (!val) efun::m_delete(err,key); 00275 } 00276 warnings[uid][hashkey]=err; 00277 00278 lasterror[T_RTWARN]=hashkey; 00279 // DEBUG(sprintf("LogWarning: Warnungseintrag:\n%O\n", 00280 // warnings[uid][hashkey])); 00281 // DEBUG(sprintf("LogWarning: Verbrauchte Ticks: %d\n", 00282 // 200000-get_eval_cost())); 00283 return(hashkey); 00284 }

| public string NotifyDestruct | ( | object | caller | ) |
Definiert in Zeile 1215 der Datei errord.c.
Benutzt ARCH_SECURITY und process_call().
01215 { 01216 if( (caller!=this_object() && !ARCH_SECURITY) || process_call() ) { 01217 return "Du darfst den Error-Daemon nicht zerstoeren!\n"; 01218 } 01219 return 0; 01220 }

| mixed QueryAll | ( | int | type | ) |
Definiert in Zeile 637 der Datei errord.c.
00637 { 00638 //das koennte ein sehr sehr grosses Mapping sein, ausserdem wird keine 00639 //Kopie zurueckgegeben, daher erstmal nur ich... 00640 if (!this_interactive() || 00641 member(MAINTAINER,getuid(this_interactive()))<0) 00642 return(-1); 00643 if (process_call()) return(-2); 00644 if (!type) return(-3); 00645 return(errors[type]); 00646 }
| varargs mapping QueryError | ( | string | hashkey, | |
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 381 der Datei errord.c.
Benutzt err, F_READSTAMP, filter_private(), getError() und resolved.
Wird benutzt von QueryLastError().
00381 { 00382 mapping err; 00383 00384 // Wenn Fehler bei den erledigten steht, einfach den zurueckgeben. 00385 if (member(resolved, hashkey)) 00386 return(filter_private(hashkey,resolved[hashkey])); 00387 00388 err=getError(hashkey,type,uid); 00389 if (!mappingp(err)) return(([])); 00390 00391 err[F_READSTAMP]=time(); 00392 //filter_private macht ne Kopie des Fehlereintrags. 00393 return(filter_private(hashkey, err)); 00394 return(([])); 00395 }


| varargs string* QueryErrorIDs | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 410 der Datei errord.c.
00410 { 00411 //alle Errorkeys (einer UID) liefern 00412 mapping mapp; 00413 string *uids,*ids; 00414 00415 if (!type) 00416 return(({})); 00417 //fuer eine UID 00418 if (stringp(uid) && strlen(uid)) { 00419 mapp=errors[type]; 00420 if (!member(mapp,uid) || !mappingp(mapp[uid])) 00421 return(({})); 00422 return(m_indices(mapp[uid])); 00423 } 00424 //fuer alle UIDs 00425 uids=QueryUIDsForType(type); 00426 ids=({}); 00427 foreach(uid: uids) { 00428 ids+=QueryErrorIDs(type,uid); 00429 } 00430 return(ids); 00431 }
| varargs int QueryErrorNo | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 472 der Datei errord.c.
00472 { 00473 //For now 00474 return(QueryUniqueErrorNo(type,uid)); 00475 }
| private int queryErrorNoForUID | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 989 der Datei errord.c.
Benutzt queryUniqueErrorNoForUID().
00989 { 00990 //For now 00991 return(queryUniqueErrorNoForUID(type,uid)); 00992 }

| mapping QueryErrors | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 397 der Datei errord.c.
Benutzt errors.
00397 { 00398 //liefert alle Fehler eines Typs und einer UID 00399 mapping mapp; 00400 if (!type || !stringp(uid) || !strlen(uid)) 00401 return(([])); 00402 mapp=errors[type]; 00403 if (!member(mapp,uid) 00404 || !mappingp(mapp[uid])) 00405 return(([])); 00406 //filter_private macht Kopien der Fehlereintraege 00407 return(map(mapp[uid],#'filter_private)); 00408 }
| mapping QueryLastError | ( | int | type | ) |
Definiert in Zeile 371 der Datei errord.c.
Benutzt lasterror und QueryError().
00371 { 00372 00373 if (!member(lasterror,type)) return ([]); 00374 //einfach den kompletten letzten Eintrag zurueckliefern 00375 return(QueryError(lasterror[type],type)); 00376 }

| mixed QueryResolved | ( | ) |
Definiert in Zeile 648 der Datei errord.c.
00648 { 00649 //das koennte ein sehr sehr grosses Mapping sein, ausserdem wird keine 00650 //Kopie zurueckgegeben, daher erstmal nur ich... 00651 if (!this_interactive() || 00652 member(MAINTAINER,getuid(this_interactive()))<0) 00653 return(-1); 00654 if (process_call()) return(-2); 00655 return(resolved); 00656 }
| varargs string* QueryUIDsForType | ( | int | type | ) |
Definiert in Zeile 433 der Datei errord.c.
00433 { 00434 //liefert alle UIDs fuer einen Fehlertyp oder fuer alle Fehlertypen 00435 string *uids; 00436 00437 if (type) { 00438 return(m_indices(errors[type])); 00439 } 00440 00441 uids=({}); 00442 foreach(type: m_indices(errors)) { 00443 uids+=QueryUIDsForType(type); 00444 } 00445 return(uids); 00446 }
| varargs int QueryUniqueErrorNo | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 449 der Datei errord.c.
00449 { 00450 int zahl; 00451 00452 if (type && stringp(uid) || strlen(uid)) 00453 return(queryUniqueErrorNoForUID(type,uid)); 00454 00455 //wenn kein Typ gegeben, wirds aufwaendig... 00456 if (!type) { 00457 foreach(type: m_indices(errors)) { 00458 //rekursion ist 'toll'... :-/ 00459 zahl+=QueryUniqueErrorNo(type); 00460 } 00461 return(zahl); //puuh. 00462 } 00463 00464 //ok, zaehlen wir ueber alle UIDs. 00465 foreach(uid: QueryUIDsForType(type)) { 00466 zahl+=queryUniqueErrorNoForUID(type,uid); 00467 } 00468 return(zahl); 00469 }
| private int queryUniqueErrorNoForUID | ( | int | type, | |
| string | uid | |||
| ) |
Definiert in Zeile 979 der Datei errord.c.
Benutzt errors.
Wird benutzt von queryErrorNoForUID().
00979 { 00980 mapping mapp; 00981 if (!type || !stringp(uid) || !strlen(uid)) 00982 return(0); 00983 mapp=errors[type]; 00984 if (!member(mapp,uid)) return(0); 00985 return(sizeof(mapp[uid])); 00986 }

| varargs int ReassignError | ( | string | hashkey, | |
| string | newuid, | |||
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 566 der Datei errord.c.
Benutzt access_check(), call_out(), errors, F_TYPE, F_UID und getError().
00567 { 00568 mapping err, errs; 00569 00570 err=getError(hashkey,type,uid); 00571 if (!mappingp(err)) return(-1); 00572 uid = err[F_UID]; 00573 00574 if (!access_check(uid, M_WRITE)) 00575 //zugriff zum Schreiben nicht gestattet 00576 return(-2); 00577 00578 if (!stringp(newuid) || !strlen(newuid)) 00579 return(-3); 00580 00581 errs = errors[err[F_TYPE]]; 00582 if (!member(errs, newuid)) errs+=([newuid:([])]); 00583 if (!mappingp(errs[newuid])) errs[newuid]=([]); 00584 00585 // momentan erstmal abbrechen, eigentlich darf das nicht vorkommen, weil 00586 // die Hashes eindeutig sein sollen. 00587 if (member(errs[newuid],hashkey)) return(-4); 00588 00589 if (!stringp(note)) note=0; 00590 00591 call_out(#'save_me,2); 00592 00593 err[F_UID] = newuid; 00594 errs[newuid] += ([hashkey: err]); 00595 efun::m_delete(errs[uid], hashkey); 00596 00597 if (!pointerp(err[F_NOTES])) 00598 err[F_NOTES]=({}); 00599 err[F_NOTES]+=({ ({time(),getuid(TI), 00600 sprintf("Fehler von %s an %s uebertragen. (%s)", 00601 uid, newuid, 00602 note ? note: "<kein Kommentar>")}) }); 00603 00604 return 1; 00605 }

| varargs int remove | ( | int | silent | ) |
| varargs int ReOpenError | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 529 der Datei errord.c.
Benutzt set_resolution().
00529 { 00530 return set_resolution(hashkey, 0, note, type, uid); 00531 }

| void reset | ( | void | ) |
Definiert in Zeile 1208 der Datei errord.c.
Benutzt archive() und set_next_reset().
01208 { 01209 archive(); // und _expire() wird von archive() gerufen 01210 //_expire(time()-(STDEXPIRE)); //21 Tage 01211 set_next_reset(3600*24); 01212 }

| varargs int ResolveError | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 525 der Datei errord.c.
Benutzt set_resolution().
00525 { 00526 return set_resolution(hashkey, 1, note, type, uid); 00527 }

| void save_me | ( | ) |
Definiert in Zeile 698 der Datei errord.c.
00698 { 00699 save_object(SAVEFILE); 00700 }
| private varargs mixed set_lock | ( | string | hashkey, | |
| int | lock, | |||
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 838 der Datei errord.c.
Benutzt access_check(), call_out(), err, F_UID, getError() und resolved.
Wird benutzt von LockError() und UnlockError().
00839 { 00840 mapping err; 00841 00842 if (member(resolved,hashkey)) 00843 return(-4); // gefixte Fehler koennen nicht gelockt/entsperrt werden. 00844 err=getError(hashkey,type,uid); 00845 if (!mappingp(err)) return(-1); 00846 00847 if (!access_check(err[F_UID], M_WRITE)) 00848 //zugriff zum Schreiben nicht gestattet 00849 return(-2); 00850 00851 // falls hier jemand was anderes als String oder 0 uebergeben hat. 00852 if (!stringp(note)) note=0; 00853 00854 if (!pointerp(err[F_NOTES])) 00855 err[F_NOTES]=({}); 00856 00857 call_out(#'save_me,2); 00858 00859 if (lock) { 00860 // wenn schon gesperrt: Lockinfos zurueckgeben und Ende 00861 if ((err[F_STATE] & STAT_LOCKED) && 00862 pointerp(err[F_LOCK])) 00863 return (copy(err[F_LOCK])); 00864 // sonst sperren 00865 err[F_STATE] |= STAT_LOCKED; 00866 // wurde gesperrt, Infos eintragen 00867 err[F_LOCK]=({time(),getuid(TI)}); 00868 err[F_NOTES]+=({ ({time(),getuid(TI), 00869 sprintf("Lock gesetzt: %s", 00870 note ? note : "<kein Kommentar>") }) }); 00871 return(copy(err[F_LOCK])); 00872 } 00873 else { 00874 // entsperren 00875 if ((err[F_STATE] & STAT_LOCKED) && 00876 pointerp(err[F_LOCK])) { 00877 err[F_STATE] &= ~STAT_LOCKED; 00878 efun::m_delete(err,F_LOCK); 00879 err[F_NOTES]+=({ ({time(),getuid(TI), 00880 sprintf("Lock geloescht: %s", 00881 note ? note : "<kein Kommentar>") }) }); 00882 } 00883 return(1); 00884 } 00885 return(-3); 00886 }


| private varargs int set_resolution | ( | string | hashkey, | |
| int | res, | |||
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 918 der Datei errord.c.
Wird benutzt von ReOpenError() und ResolveError().
00919 { 00920 mapping err; 00921 00922 if (member(resolved,hashkey)) 00923 err=resolved[hashkey]; 00924 else { 00925 //Fehler holen, dabei sollen Infos wie UID, Hashkey mit _in_ den 00926 //Fehlereintrage geschrieben werden. 00927 err=getError(hashkey,type,uid,1); 00928 if (!mappingp(err)) return(-1); 00929 } 00930 00931 if (!access_check(err[F_UID], M_WRITE)) 00932 //zugriff zum Schreiben nicht gestattet 00933 return(-2); 00934 00935 // falls hier jemand was anderes als String oder 0 uebergeben hat. 00936 if (!stringp(note)) note=0; 00937 00938 if (!pointerp(err[F_NOTES])) 00939 err[F_NOTES]=({}); 00940 // gna, alte Fehler haben den hashkey nicht drinnen. 00941 if (!member(err,F_HASHKEY)) 00942 err[F_HASHKEY]= hashkey; 00943 00944 call_out(#'save_me,2); 00945 00946 if (res && !(err[F_STATE] & STAT_RESOLVED)) { 00947 // soll als erledigt markiert und ist nicht erledigt. 00948 err[F_STATE] |= STAT_RESOLVED; 00949 err[F_NOTES]+= ({ ({time(),getuid(TI), 00950 sprintf("Fehler gefixt: %s", 00951 note ? note : "<kein Kommentar>") }) }); 00952 // UID und Typ stehen im Fehlereintrag drin. 00953 resolved[hashkey]=err; // in resolved wegschreiben zur Archivierung 00954 versende_mail(err); // per Mail verschicken 00955 // und aus dem normaler Fehlermapping loeschen 00956 efun::m_delete(errors[err[F_TYPE]][err[F_UID]],hashkey); 00957 return(1); 00958 } 00959 else if (!res && err[F_STATE] & STAT_RESOLVED) { 00960 // soll als nicht-erledigt markiert werden und ist erledigt. 00961 err[F_STATE] &= ~STAT_RESOLVED; 00962 err[F_NOTES]+= ({ ({time(),getuid(TI), 00963 sprintf("Fix zurueckgezogen: %s", 00964 note ? note : "<kein Kommentar>") }) }); 00965 if (!member(errors,err[F_TYPE])) 00966 errors[err[F_TYPE]]=([]); 00967 if (!member(errors[err[F_TYPE]],err[F_UID])) 00968 errors[err[F_TYPE]][err[F_UID]]=([]); 00969 //Fehler wieder in normales Fehlermapping schreiben 00970 errors[err[F_TYPE]][err[F_UID]][hashkey]=err; 00971 efun::m_delete(resolved,hashkey); 00972 return(1); 00973 } 00974 // offenbar schon so markiert, wie man gerade wuenscht. 00975 return(-3); 00976 }

| varargs int ToggleDeleteError | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 480 der Datei errord.c.
00481 { 00482 mapping err; 00483 00484 err=getError(hashkey,type,uid); 00485 if (!mappingp(err)) return(-1); 00486 00487 if (!access_check(err[F_UID], M_WRITE)) 00488 //zugriff zum Schreiben nicht gestattet 00489 return(-2); 00490 00491 if (!stringp(note)) note=0; 00492 00493 call_out(#'save_me,2); 00494 00495 if (!pointerp(err[F_NOTES])) 00496 err[F_NOTES]=({}); 00497 err[F_STATE] ^= STAT_DELETED; 00498 if (err[F_STATE] & STAT_DELETED) { 00499 err[F_NOTES]+=({ ({time(),getuid(TI), 00500 sprintf("Loeschmarkierung gesetzt. (%s)", 00501 note ? note: "<kein Kommentar>")}) }); 00502 return(1); // Loeschmarkierung gesetzt. 00503 } 00504 else { 00505 err[F_NOTES]+=({ ({time(),getuid(TI), 00506 sprintf("Loeschmarkierung entfernt. (%s)", 00507 note ? note : "<kein Kommentar>")}) }); 00508 return(2); // Loeschmarkierung entfernt. 00509 } 00510 return(-1); 00511 }
| varargs int UnlockError | ( | string | hashkey, | |
| string | note, | |||
| int | type, | |||
| string | uid | |||
| ) |
Definiert in Zeile 520 der Datei errord.c.
Benutzt set_lock().
00520 { 00521 return (int)set_lock(hashkey, 0, note, type, uid); 00522 }

| private int versende_mail | ( | mapping | fehler | ) |
Definiert in Zeile 1153 der Datei errord.c.
Benutzt break_string(), BS_LEAVE_MY_LFS, DeliverMail(), dtime(), F_CLI, F_HASHKEY, F_LOADNAME, format_error(), m_delete(), master, MSG_BCC, MSG_BODY, MSG_CC, MSG_DATE, MSG_FROM, MSG_ID, MSG_RECIPIENT, MSG_SENDER, MSG_SUBJECT, MUDNAME, text() und TI.
01153 { 01154 // Versendet eine mail mit dem gefixten Fehler. 01155 mixed *mail; 01156 string text, *empf; 01157 01158 empf = (string*)master()->QueryWizardsForUID(fehler[F_UID]); 01159 if (!sizeof(empf)) return -1; // leider keine Empfaenger ermittelbar 01160 01161 mail = allocate(9); 01162 01163 // hier mal kein efun::m_delete(), ich brauch ne Kopie ohne das F_CLI, auch 01164 // wenn ein EM fixt, sollen die Empfaenger nicht automatisch die 01165 // Spielereingabe erhalten. 01166 fehler = m_delete(fehler, F_CLI); 01167 01168 text = break_string( 01169 sprintf(STANDARDMAILTEXT,capitalize(getuid(TI))) 01170 +format_error(fehler[F_HASHKEY],fehler),78,"",BS_LEAVE_MY_LFS); 01171 01172 mail[MSG_FROM] = "<Fehler-Daemon>"; 01173 mail[MSG_SENDER] = getuid(TI); 01174 mail[MSG_RECIPIENT] = empf[0]; 01175 if (sizeof(empf)>1) 01176 mail[MSG_CC] = empf[1..]; 01177 else 01178 mail[MSG_CC] = 0; 01179 mail[MSG_BCC] = 0; 01180 mail[MSG_SUBJECT] = sprintf("Fehler in %s behoben",fehler[F_LOADNAME]); 01181 mail[MSG_DATE] = dtime(time()); 01182 mail[MSG_ID]=sprintf(MUDNAME": %d.%d",time(),random(__INT_MAX__)); 01183 mail[MSG_BODY]=text; 01184 01185 if (!sizeof("/secure/mailer"->DeliverMail(mail,0))) 01186 return -2; // an niemanden erfolgreich zugestellt. :-( 01187 01188 return 1; 01189 }

| mapping errors |
Definiert in Zeile 32 der Datei errord.c.
Wird benutzt von LogCompileProblem(), LogError(), LogWarning(), QueryErrors(), queryUniqueErrorNoForUID() und ReassignError().
| nosave mapping lasterror |
Definiert in Zeile 35 der Datei errord.c.
Wird benutzt von LogCompileProblem(), LogError(), LogWarning() und QueryLastError().
| mapping resolved |
Definiert in Zeile 33 der Datei errord.c.
Wird benutzt von AddNote(), archive(), QueryError() und set_lock().
1.6.3