// // Enkel databas i en l}ng fil. // // Formatet f|r filen {r: // post \n\n post // Formatet f|r varje post {r: // f{lt \n f{lt \n f{lt ... s} m}nga som det nu {r... // inga f{lt f}r vara tomma. // // #define DEBUG #define DATABASEFILE "/usr/www/html/svmud/spelare/linus/data/DB" #define PASSWDFILE "/usr/www/html/svmud/spelare/linus/data/passwd" #define SVMUDPLAYERS "/usr/svmud/lib/spelare/" #define ADMIN "linus" inherit "http"; array (array(string)) data = ({ }); void load_data() { data = map_array(explode(read_bytes(DATABASEFILE), "\n\n"), lambda(string record) { return explode(record, "\n") - ({ "", }); }) - ({ ({ }) }); } void save_data() { rm(DATABASEFILE + ".old"); mv(DATABASEFILE, DATABASEFILE + ".old"); write_file(DATABASEFILE, implode(map_array(data, lambda(array(string) record) { return implode(record,"\n"); }), "\n\n")); } void prepare_to_save() { remove_call_out(save_data); call_out(save_data, 1); } // These macros are used to find the correct record. #define RECORD_NAME(rec) (rec)[0] #define RECORD_PASSWORD(rec) (rec)[1] #define RECORD_REALNAME(rec) (rec)[2] #define RECORD_REALADDRESS(rec) (rec)[3] #define RECORD_PHONE(rec) (rec)[4] #define RECORD_EMAIL(rec) (rec)[5] #define RECORD_HOMEPAGE(rec) (rec)[6] #define RECORD_PICTURE(rec) (rec)[7] #define RECORD_ORIGINALLYFROM(rec) (rec)[8] #define RECORD_BECAMEWIZARD(rec) (rec)[9] #define RECORD_OTHER_INFO(rec) (rec)[10] #define RECORD_LAST_MODIFIED(rec) (rec)[11] #define VERIFY_ARRAY_SIZE(rec) while (sizeof(rec) < 12) { rec += ({ "" }); } // Removes all items with the name name from data. void remove_from_array(string name) { int i; for (i = 0; i < sizeof(data); i++) { if (RECORD_NAME(data[i]) == name) { data -= ({ data[i], }); i--; } } } void add_to_array(array(string) record) { int i; for(i = 0; i < sizeof(record); i++) { record[i] = replace(record[i], ({ "\n", "\r", }), ({ " ", " ", })); if (record[i] == "") record[i] = "0"; } data += ({ record }); } mapping data_index; // Resets the index void reset_index() { data_index = 0; } // Builds or rebuilds the index. void rebuild_index() { data_index = mkmapping(map_array(data, lambda(array(string) record) { return RECORD_NAME(record); }), data); } // Builds the index if not already built. void build_index() { if (mappingp(data_index)) return; rebuild_index(); } void create() { load_data(); reset_index(); } // This returns 0 if not found. array(string) get(string name) { build_index(); if (arrayp(data_index[name])) return map_array(data_index[name], lambda(string info) { if (info == "0") return ""; else return info; }); else return 0; } // Adds or modifies an entry. void put(array(string) record) { reset_index(); remove_from_array(RECORD_NAME(record)); add_to_array(record); prepare_to_save(); } void delete(string name) { reset_index(); remove_from_array(name); prepare_to_save(); } array(string) all_entries() { build_index(); return indices(data_index); } // End of database things string filename; string basename(string name) { array(string) a = explode(name,"/"); return filename = a[sizeof(a) - 1]; } // Things that help in the authentication // Generate a new record containing name and password for a user not in // the database. // First search in the passwd-format-like file. Then in the svmud data files. mapping passwd = 0; array(string) generate_new_passwd(string name) { name = lower_case(name); if (passwd == 0) { // Read the passwd-format file. passwd = sum(@map_array((explode(read_bytes(PASSWDFILE) || "", "\n")), lambda(string entry) { array(string) arr = explode(entry, ":"); if (sizeof(arr) < 2) return ([ ]); return ([arr[0]:arr[1]]); })); } if (passwd[name]) { return ({ name, passwd[name], }); } return 0; } array(string) generate_new_datafile(string name) { string pass; string filecont; name = lower_case(name); if ((filecont = read_bytes(SVMUDPLAYERS + name + ".o")) && sscanf(filecont, "%*s\npassword \"%s\"", pass)) { return ({ name, pass, }); } return 0; } // Convert an auth record to a name. string auth_to_name(array(string) arr) { return lower_case(arr[1]); } string auth_to_password(array(string) arr) { return arr[2]; } // Return true if the auth record identifies a user correctly // Actually it returns 1 if in the database, 2 if in the passwd-style file // and 3 if in the datafile (4 if the password is allready identified by // the user db of roxen. int auth_is_correct(array(string) arr) { array(string) record; if (arr && sizeof(arr) >= 3 && arr[0] && stringp(auth_to_name(arr)) && generate_new_datafile(auth_to_name(arr))) return 4; if (!(arr && sizeof(arr) >= 3 && stringp(auth_to_name(arr)) && stringp(auth_to_password(arr)))) return 0; record = get(auth_to_name(arr)); if (record && sizeof(record) >= 2 && stringp(RECORD_PASSWORD(record)) && RECORD_PASSWORD(record) != "" && crypt(auth_to_password(arr), RECORD_PASSWORD(record))) return 1; record = generate_new_passwd(auth_to_name(arr)); if (record && sizeof(record) >= 2 && crypt(auth_to_password(arr), RECORD_PASSWORD(record))) return 2; record = generate_new_datafile(auth_to_name(arr)); if (record && sizeof(record) >= 2 && crypt(auth_to_password(arr), RECORD_PASSWORD(record))) return 3; return 0; } // Quote "dangerous" characters. string quote(string in) { return replace(in, ({ "\"", "<", ">", }), ({ """, "<", ">", })); } // Returns the info about one person. string info_about(string name, int with_pictures) { array(string) record = get(lower_case(name)); if (record) { VERIFY_ARRAY_SIZE(record); return (with_pictures && RECORD_PICTURE(record) != "" ? "" : "") + "
" + quote(RECORD_REALNAME(record)) + "\n" + implode(explode(quote(RECORD_REALADDRESS(record)),", "), "\n") + "" + "\n" + (RECORD_PHONE(record) != "" ? "Telefon: " + quote(RECORD_PHONE(record)) : "") + (RECORD_PHONE(record) != "" && RECORD_EMAIL(record) != "" ? ", " : "") + (RECORD_EMAIL(record) != "" ? "email: " + quote(RECORD_EMAIL(record)) + "" : "") + "
\n" + (RECORD_ORIGINALLYFROM(record) != "" ? capitalize(name) + " kommer ursprungligen från " + quote(RECORD_ORIGINALLYFROM(record)) + ".\n" : "") + "\n" + (RECORD_BECAMEWIZARD(record) != "" ? capitalize(name) + " blev magiker den " + quote(RECORD_BECAMEWIZARD(record)) + ".\n" : "") + "\n" + (RECORD_OTHER_INFO(record) != "" ? quote(RECORD_OTHER_INFO(record)) + "\n" : "") + "\n" + (RECORD_HOMEPAGE(record) != "" ? capitalize(name) + " har en egen hemsida." : "") + (RECORD_LAST_MODIFIED(record) != "" ? "
\nInformationen om " + capitalize(name)
+ " ändrades senast "
+ RECORD_LAST_MODIFIED(record)
: "")
+ "
\n";
}
else
{
return "Ingen information finns i databasen om " + name + "\n";
}
}
#define LENKARNA "[Ändra/lägg till din information] "\
+ "[All info utan bilder] " \
+ "[All info med bilder] " \
+ "[Bara de som har hemsidor] "
// Returnerar ett snabbindex där alla spelarna finns med indexerat på bokstav
string
snabbindex()
{
string current_letter = "0";
array (string) arr = sort_array((array*)all_entries(), 0, 0);
string output = "
Jag (Linus) kommer, när jag hinner, gå omkring och rätta till " + "det värsta slarvet så att denna lista blir vacker och användbar." + "
\n" + "\n" + "Ibland kanske inte ens det hjälper. Prova då att ange det lösenord du hade tidigare i Svenskmud eller om du är en ny spelare så finns du nog inte med. Tala då om problemet för Linus så kan han uppdatera lösenordsdatabasen." #ifdef DEBUG + sprintf("
\n%O\n", request->auth) + sprintf("
\n%O\n", request->auth && sizeof(request->auth) >= 3 && stringp(auth_to_name(request->auth)) && stringp(auth_to_password(request->auth)) ? generate_new_datafile(auth_to_name(request->auth)) : "arrayen inkorrekt") + sprintf("
\n%O\n", passwd) + sprintf("