diff --git a/.gitignore b/.gitignore index a18f25e..bf04e45 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /bin/steam *.so *.o +help diff --git a/server/client_base.pike b/server/client_base.pike new file mode 100644 index 0000000..f97b7fd --- /dev/null +++ b/server/client_base.pike @@ -0,0 +1,615 @@ +/* Copyright (C) 2000-2005 Thomas Bopp, Thorsten Hampel, Ludger Merkens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: client_base.pike,v 1.2 2008/07/17 16:45:00 astra Exp $ + */ + +constant cvs_version="$Id: client_base.pike,v 1.2 2008/07/17 16:45:00 astra Exp $"; + +inherit "kernel/sockets"; +inherit "net/coal/binary"; + +#include +#include +#include +#include + +#undef CLIENT_DEBUG + +#ifdef CLIENT_DEBUG +#define DEBUG_CLIENT(s, args...) werror(s+"\n", args) +#else +#define DEBUG_CLIENT(s, args...) +#endif + +private static mapping mObjects; // objects +private static string sLastPacket; // last package while communicating +private static int iOID; // the object id of the current object +private static int iTID; // the current transaction id +private static int iWaitTID; + static mapping mVariables; // session variables + static array aEvents; + static int __connected; + static int __downloadBytes; + int __last_response; + static function downloadStore; + static mapping mEvents; + +private static mixed miResult; +private static int miCommand; + +static Thread.Mutex cmd_mutex = Thread.Mutex(); +static Thread.Condition cmd_cond = Thread.Condition(); +static Thread.Queue resultQueue = Thread.Queue(); +static Thread.Queue cmdQueue = Thread.Queue(); +static object cmd_lock; + +string connected_server; +int connected_port; + + +class SteamObj +{ + private static int oID; + private static string identifier = 0; + private static int cl = 0; + private static int(0..1) nowait; + private static mapping(string:function) functions=([]); + + int get_object_id() { + return oID; + } + + int get_object_class() { + if ( cl == 0 ) { + int wid = iWaitTID; + int id = set_object(oID); + mixed res = send_command(COAL_COMMAND, ({ "get_object_class" })); + if ( intp(res) ) + cl = res; + set_object(id); + iWaitTID = wid; + } + return cl; + } + + object get_environment() { + return send_command(COAL_COMMAND, ({ "get_environment" })); + } + + string get_identifier() { + if ( !stringp(identifier) ) { + int wid = iWaitTID; + int id = set_object(oID); + identifier = send_command(COAL_COMMAND, ({ "get_identifier" })); + set_object(id); + iWaitTID = wid; + } + return identifier; + } + + void create(int id) { + oID = id; + } + + int status() { + return 1; // PSTAT_SAVE_OK + } + + int no_wait(void|int(0..1) _nowait) + { + if(!zero_type(_nowait) && nowait == !_nowait) + { + nowait=!!_nowait; + return !nowait; + } + else + return nowait; + } + + string function_name(function fun) + { + return search(functions, fun); + } + + string _sprintf() + { + return "OBJ#"+oID; + string describe=""; + catch{ describe=`->("describe")(); }; + return sprintf("%s:%d/%s", connected_server, connected_port, describe); + } + + function `->(string fun) + { + if(::`->(fun)) + return ::`->(fun); + else + { + if(fun == "exec_code") + return 0; + else if (fun=="serialize_coal") + return 0; + if(!functions->fun) + functions[fun]=lambda(mixed|void ... args) { + return send_cmd(oID, fun, args, nowait); + }; + return functions[fun]; + } + } + + function find_function(string fun) + { + if(!functions->fun) + functions[fun]=lambda(mixed|void ... args) { + return send_cmd(oID, fun, args, nowait); + }; + return functions[fun]; + } +}; + + +/** + * + * + * @param + * @return + * @author Thomas Bopp) + * @see + */ +int set_object(int|object|string id) +{ + int oldID = iOID; + + if ( stringp(id) ) { + if ( objectp(mVariables[id]) ) + iOID = mVariables[id]->get_object_id(); + else + iOID = mVariables[id]; + } + else if ( objectp(id) ) + iOID = id->get_object_id(); + else + iOID = id; + return oldID; +} + +/** + * + * + * @param + * @return + * @author Thomas Bopp (astra@upb.de) + * @see + */ +static object find_obj(int|string id) +{ + int oid; + if ( stringp(id) ) { + object fp = send_cmd( 0, "get_module", "filepath:tree" ); + object obj = send_cmd( fp, "path_to_object", id ); + if ( !objectp(obj) ) return 0; + oid = obj->get_object_id(); + } + else oid = id; + + if ( !mObjects[oid] ) { + mObjects[oid] = SteamObj(oid); + //werror("Created:"+master()->describe_object(mObjects[id])+"\n"); + } + return mObjects[oid]; +} + +object find_object(int|string id) { return find_obj(id); } + +mixed get_variable(string key) +{ + return mVariables[key]; +} + +/** + * + * + * @param + * @return + * @author Thomas Bopp (astra@upb.de) + * @see + */ +int connect_server(string server, int port) +{ + iTID = 1; + iOID = 0; + sLastPacket = ""; + __downloadBytes = 0; + mVariables = ([ ]); + mObjects = ([ ]); + aEvents = ({ }); + mEvents = ([ ]); + + sock->open_socket(); + sock->set_blocking(); + if ( sock->connect(server, port) ) { + connect_ssl(); + MESSAGE("Connected to " + server + ":"+port +"\n"); + connected_server=server; + connected_port=port; + __last_response = time(); // timestamp of last response + __connected = 1; + sock->set_buffer(65536, "r"); + sock->set_buffer(65536, "w"); + set_blocking(); + thread_create(read_thread); + thread_create(handle_commands); + return 1; + } + return 0; +} + +void create() +{ +} + +static int write(string str) +{ + __last_response = time(); + return ::write(str); +} + +static void handle_command(string func, mixed args) { } + +void handle_commands() +{ + mixed res; + while ( res = cmdQueue->read() ) { + if ( arrayp(res) ) { + if ( arrayp(res[1]) ) { + mixed err = catch { + handle_command(res[1][0], res[1][1]); + }; + if ( err != 0 ) + werror("Fatal error while calling command: %O\n%O", err[0], err[1]); + } + } + } +} + + +void read_callback(object id, string data) +{ + __last_response = time(); + + if ( functionp(downloadStore) ) { + mixed err = catch { + downloadStore(data); + }; + __downloadBytes -= strlen(data); + if ( __downloadBytes <= 0 ) { + downloadStore(0); + downloadStore = 0; // download finished + } + return; + } + sLastPacket += data; + if ( __downloadBytes > 0 ) { + if ( __downloadBytes <= strlen(sLastPacket) ) + resultQueue->write(sLastPacket); + return; + } + mixed res; + res = receive_binary(sLastPacket); + while ( arrayp(res) ) { + int tid = res[0][0]; + int cmd = res[0][1]; + + if ( cmd == COAL_EVENT ) { + DEBUG_CLIENT("Event %O", res[1]); + } + DEBUG_CLIENT("RCVD Package(%d): Waiting for %d\n", tid, iWaitTID); + sLastPacket = res[2]; + if ( tid == iWaitTID ) { + miResult = res[1]; + miCommand = res[0][1]; + resultQueue->write(miResult); + } + else if ( cmd == COAL_COMMAND ) { + cmdQueue->write(res); + } + res = receive_binary(sLastPacket); + } +} + +string download(int bytes, void|function store) +{ + // actually the last command should have been the upload response, + // so there shouldnt be anything on the line except events + // which should have been already processed + // everything else should be download data + string data; + __downloadBytes = bytes; + + if ( functionp(store) ) { + data = copy_value(sLastPacket[..bytes]); + __downloadBytes -= strlen(data); + if ( strlen(data) > 0 ) + store(data); + if ( __downloadBytes <= 0 ) { + store(0); + return ""; + } + downloadStore = store; + return ""; + } + downloadStore = 0; + + if ( strlen(sLastPacket) >= bytes ) { + data = copy_value(sLastPacket[..bytes]); + if ( bytes > strlen(sLastPacket) ) + sLastPacket = sLastPacket[bytes+1..]; + else + sLastPacket = ""; + __downloadBytes = 0; + return data; + } + + miResult = resultQueue->read(); + data = copy_value(sLastPacket[..bytes]); + if ( strlen(sLastPacket) > bytes ) + sLastPacket = sLastPacket[bytes+1..]; + else + sLastPacket = ""; + __downloadBytes = 0; + return data; +} + +/** + * + * + * @param + * @return + * @author Thomas Bopp) + * @see + */ +void handle_error(mixed err) +{ + throw(err); +} + +/** + * + * + * @param + * @return + * @author Thomas Bopp (astra@upb.de) + * @see + */ +mixed send_command(int cmd, array(mixed) args, int|void no_wait) +{ + if ( !no_wait ) iWaitTID = iTID; + aEvents = ({ }); + + + string msg = coal_compose(iTID++, cmd, iOID, 0, args); + string nmsg = copy_value(msg); + + send_message(nmsg); + if ( no_wait ) return 0; + + mixed result = resultQueue->read(); + if ( miCommand == COAL_ERROR ) { + handle_error(result); + } + return result; +} + +void subscribe_event(object obj, int eid, function callback) +{ + int oid = set_object(obj); + send_command(COAL_SUBSCRIBE, ({ eid }) ); + mEvents[eid] = callback; + set_object(oid); +} + +mixed send_cmd(object|int obj, string func, mixed|void args, void|int no_wait) +{ + int oid = set_object(obj); + if ( zero_type(args) ) + args = ({ }); + else if ( !arrayp(args) ) + args = ({ args }); + mixed res = send_command(COAL_COMMAND, ({ func, args }), no_wait); + set_object(oid); + return res; +} + +mixed +login(string name, string pw, int features, string|void cname, int|void novars) +{ + if ( !stringp(cname) ) + cname = "steam-pike"; + + mixed loginData; + if ( features != 0 ) + loginData =send_command(COAL_LOGIN, ({ name, pw, cname, features, __id })); + else + loginData = + send_command(COAL_LOGIN,({ name, pw, cname,CLIENT_FEATURES_ALL, __id})); + + if ( arrayp(loginData) && sizeof(loginData) >= 9 ) { + mVariables["user"] = iOID; + foreach ( indices(loginData[8]), string key ) { + mVariables[key] = loginData[8][key]; + } + mVariables["rootroom"] = loginData[6]; + sLastPacket = ""; + if ( novars != 1 ) { + foreach ( values(loginData[9]), object cl ) { + set_object(cl->get_object_id()); + mVariables[send_cmd(cl,"get_identifier")] = cl; + } + } + return name; + } + return 0; +} + +mixed logout() +{ + __connected = 0; + write(coal_compose(0, COAL_LOGOUT, 0, 0, 0)); +} + + +void was_closed() +{ + resultQueue->write(""); + ::was_closed(); +} + + +void write_error2file(mixed|string err, int recursive) { + + Stdio.File error_file; + string path; + array(string) directory; + int file_counter =0; + int found=0; + path = getcwd(); + directory = get_dir(path); + while (found==0){ + int tmp_found=1; + tmp_found=Stdio.exist(path+"/install_error."+file_counter); + if (tmp_found==1){ + file_counter = file_counter + 1; + } + else{ + found = 1; + } + } + + if (recursive==1) + file_counter = file_counter -1; + error_file=Stdio.File (path+"/install_error."+file_counter ,"cwa"); + if (stringp (err)){ + error_file->write(err); + } + if(arrayp(err)){ + foreach(err, mixed error){ + if ( stringp(error) || intp(error) ) + error_file->write((string)error); + else if ( objectp(error) ) + error_file->write("\n"); + else if ( arrayp(error) ){ + write_error2file(error,1); + } + } + } + if (recursive!=0) + error_file->close(); +} + + +/** + * Creates a new document object on the server. + * + * @param name the name of the new object + * @param where the container or room in which to create the new object + * @param mimetype (optional) the mime type of the new object (if not + * specified, the mime type will be determined by the object name) + * @param content (optional) the content for the new object (if not specified, + * the new object will not have any content) + * @return the newly created object (if an error occurs, an exception will be + * thrown instead) + */ +object create_document ( string name, object where, void|string mimetype, void|string content ) +{ + if ( !stringp(name) || sizeof(name) < 1 ) + throw( ({ "No name specified !" }) ); + if ( !objectp(where) ) + throw( ({ "No room or container specified !" }) ); + object obj = send_cmd( where, "get_object_byname", name ); + if ( objectp(obj) ) + throw( ({ "Object \""+name+"\" already found !" }) ); + object factory = send_cmd( 0, "get_factory", CLASS_DOCUMENT ); + if ( !objectp(factory) ) + throw( ({ "Document factory not found on server !" }) ); + mapping params = ([ "name":name ]); + if ( stringp(mimetype) && sizeof(mimetype) > 0 ) + params["mimetype"] = mimetype; + obj = send_cmd( factory, "execute", params ); + if ( !objectp(obj) ) + throw( ({ "Could not create document !" }) ); + send_cmd( obj, "move", where ); + + if ( stringp(content) ) + send_cmd( obj, "set_content", content ); + + return obj; +} + + +/** + * Creates a new room object on the server. + * + * @param name the name of the new object + * @param where the room in which to create the new object + * @return the newly created object (if an error occurs, an exception will be + * thrown instead) + */ +object create_room ( string name, object where ) +{ + if ( !stringp(name) || sizeof(name) < 1 ) + throw( ({ "No name specified !" }) ); + if ( !objectp(where) ) + throw( ({ "No room specified !" }) ); + object obj = send_cmd( where, "get_object_byname", name ); + if ( objectp(obj) ) + throw( ({ "Object \""+name+"\" already found !" }) ); + object factory = send_cmd( 0, "get_factory", CLASS_ROOM ); + if ( !objectp(factory) ) + throw( ({ "Room factory not found on server !" }) ); + obj = send_cmd( factory, "execute", ([ "name":name ]) ); + if ( !objectp(obj) ) + throw( ({ "Could not create room !" }) ); + send_cmd( obj, "move", where ); + return obj; +} + +/** + * Creates a new container object on the server. + * + * @param name the name of the new object + * @param where the container or room in which to create the new object + * @return the newly created object (if an error occurs, an exception will be + * thrown instead) + */ +object create_container ( string name, object where ) +{ + if ( !stringp(name) || sizeof(name) < 1 ) + throw( ({ "No name specified !" }) ); + if ( !objectp(where) ) + throw( ({ "No room or container specified !" }) ); + object obj = send_cmd( where, "get_object_byname", name ); + if ( objectp(obj) ) + throw( ({ "Object \""+name+"\" already found !" }) ); + object factory = send_cmd( 0, "get_factory", CLASS_CONTAINER ); + if ( !objectp(factory) ) + throw( ({ "Container factory not found on server !" }) ); + obj = send_cmd( factory, "execute", ([ "name":name ]) ); + if ( !objectp(obj) ) + throw( ({ "Could not create container !" }) ); + send_cmd( obj, "move", where ); + return obj; +} diff --git a/server/kernel/sockets.pike b/server/kernel/sockets.pike new file mode 100644 index 0000000..bb0c0ed --- /dev/null +++ b/server/kernel/sockets.pike @@ -0,0 +1,344 @@ +/* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: socket.pike,v 1.2 2009/08/04 16:28:01 nicke Exp $ + */ + +constant cvs_version="$Id: socket.pike,v 1.2 2009/08/04 16:28:01 nicke Exp $"; + +inherit SSL.sslfile : socket; + +#include +#include +#include +#include + +Stdio.File sock = Stdio.File(); + +private static string __buffer; +private static int __len; +private static function fWriteFunction; +private static function fFinishFunction; + +#ifdef THREAD_READ +private static Thread.Condition write_cond = Thread.Condition(); +private static Thread.Mutex read_mutex = Thread.Mutex(); +private static Thread.Queue msgQueue = Thread.Queue(); +private static Thread.Queue closeQueue = Thread.Queue(); +#endif + +#ifdef SOCKET_DEBUG +#define DEBUG(s) werror("["+__id+"] "+s+"\n") +#else +#define DEBUG(s) +#endif + +#define ISCLOSED (closeQueue->size() > 0) + +int __id; + +void connect_ssl(){ + ::create(sock,SSL.context(),1,1); +} + +/** + * + * + * @param + * @return + * @author Thomas Bopp + * @see + */ +static void +disconnect() +{ + DEBUG("DISCONNECT()\n"); + mixed err = catch { + ::close(); + sock->close(); + }; + if ( err != 0 ) + DEBUG("While disconnecting socket:\n"+sprintf("%O",err)); + if ( objectp(read_mutex) ) + destruct(read_mutex); +} + +/** + * send a message to the client + * + * @param str - the message to send + * @author Thomas Bopp + * @see write_callback + */ +static void send_message(string str) +{ + DEBUG("send_message("+strlen(str)+" bytes...)"); + msgQueue->write(str); +} + +/** + * this function is called when there is free space for writting + * + * @author Thomas Bopp (astra@upb.de) + * @see read_callback + * @see register_send_function + * @see send_message + */ +static void write_callback(string __buffer) +{ + int written; + mixed w; + int len; + + DEBUG("write_callback("+strlen(__buffer)+ + ", closed?"+(ISCLOSED?"true":"false")); + + + if ( ISCLOSED ) return; + + len = strlen(__buffer); + + if ( functionp(fWriteFunction) ) { + w = fWriteFunction(__len); + + if ( !stringp(w) ) { + fFinishFunction(); + fWriteFunction = 0; + fFinishFunction = 0; + } + else { + __len += strlen(w); + msgQueue->write(w); + } + } + while ( strlen(__buffer) > 0 ) { + mixed err = catch { + written = write(__buffer); + DEBUG("written " + written + " bytes..."); + }; + if ( err != 0 ) { + __buffer = ""; + DEBUG("error while writting:\n"+sprintf("%O\n",err)); + return; + } + + if ( written < 0 ) { + return; + } + if ( written < strlen(__buffer ) ) { + if ( written > 0 ) + __buffer = __buffer[written..]; + else if ( written == 0 ) + sleep(0.1); + } + else + return; + } +} + +/** + * this function is called when data is received on the socket + * + * @param id - data for the socket + * @param data - the arriving data + * @author Thomas Bopp + * @see write_callback + */ +static void read_callback(mixed id, string data) +{ +} + +static void was_closed() +{ + closeQueue->write(""); +} + +/** + * The read thread reads data. + * + * @param + * @return + * @author Thomas Bopp (astra@upb.de) + * @see + */ +final static void tread_data() +{ + string str; + + if ( ISCLOSED ) return; + + mixed err = catch { + str = socket::read(SOCKET_READ_SIZE, 1); + }; + DEBUG("Returning from read...\n"); + + if ( err != 0 || !stringp(str) || strlen(str) == 0 ) { + DEBUG("Socket was closed while in read..."); + was_closed(); + } + else { + DEBUG("Reading " + strlen(str) + " bytes...\n"); + read_callback(0, str); + } +} + +/** + * close the connection to the client + * + * @author Thomas Bopp + */ +void +close_connection() +{ + DEBUG("close_connection()"); + closeQueue->write(""); + msgQueue->write(""); + + mixed err = catch { + socket::set_read_callback(0); + }; +} + +/** + * create the object (the constructor) + * + * @param f - the portobject + * @author Thomas Bopp + */ +static void create(object f) +{ + sock->assign(f); + SSL.sslfile(sock,SSL.context(),1,1); +// socket::assign(f); + __buffer = ""; + fWriteFunction = 0; + socket::set_blocking(); + sock->set_buffer(65536*10, "w"); + sock->set_buffer(65536*10, "r"); + thread_create(read_thread); +} + +/** + * Get the ip of this socket. + * + * @return the ip number 127.0.0.0 + * @author Thomas Bopp) + */ +string|int get_ip() +{ + mixed err; + string addr; + + err = catch { + addr = query_address(); + }; + if ( err != 0 ) + addr = "no connected"; + LOG("query_adress() returns " + addr); + string ip = 0; + if ( stringp(addr) ) + sscanf(addr, "%s %*d", ip); + return ip; +} + + +/** + * register a callback function for writting data to the socket + * if there is already a function defined there will be a runtime error + * + * @param f - the callback function + * @author Thomas Bopp (astra@upb.de) + * @see write_callback + */ +static void register_send_function(function f, function e) +{ + ASSERTINFO(!functionp(fWriteFunction), + "Allready defined writer function !"); + + string w = f(0); + if ( !stringp(w) ) + return; + + fWriteFunction = f; + fFinishFunction = e; + __len = strlen(w); + msgQueue->write(w); +} + + +#ifdef THREAD_READ + +/** + * The main function for the reader thread. Calls tread_data() repeatedly. + * + * @author Thomas Bopp (astra@upb.de) + * @see tread_data + */ +final static void read_thread() +{ + DEBUG("read_thread() created, now creating write_thread()..."); + + thread_create(write_thread); + while ( !ISCLOSED ) { + DEBUG("!ISCLOSED and reading data...."); + tread_data(); + } + DEBUG("Read Thread Ended...."); + closeQueue->write(""); + DEBUG("Read Thread Ended....: CloseQueue="+closeQueue->size()); + msgQueue->write("end"); +} + + +/** + * The main function for the writer thread. Calls the write_callback() + * repeatedly and waits for signals. + * + * @param + * @return + * @author Thomas Bopp (astra@upb.de) + * @see + */ +final static void +write_thread() +{ + string msg; + DEBUG("write_thread() created ..."); + while ( !ISCLOSED && (msg = msgQueue->read()) ) { + write_callback(msg); + } + DEBUG("disconnecting socket...: CloseQueue="+closeQueue->size()); + + disconnect(); + closeQueue->write(""); +} +#endif + +string describe() +{ + return "Socket("+__id+", closed="+closeQueue->size()+","+get_ip()+")"; +} + +void set_id(int i) { __id = i; } +int get_id() { return __id; } +bool is_closed() { return closeQueue->size() >= 2; } +int is_closed_num() { return closeQueue->size(); } +string get_identifier() { return "socket"; } + + + + + diff --git a/tests/coal-m4/Readme b/tests/coal-m4/Readme new file mode 100644 index 0000000..b23cf9c --- /dev/null +++ b/tests/coal-m4/Readme @@ -0,0 +1,22 @@ +The tests here use the pike scripts included to generate and run testsuites. + +mktestsuite +The mktestsuite script is a simple shell script that uses M4 to convert a testsuite input file into a testsuite that can be run by test_pike.pike. This script is found in $PIKE/include/pike. + +Usage: + +mktestsuite test.in > test + +The input file is simply a series of test invocations; any code outside of a test invocation will be ignored and will not appear in the final testsuite file. + + +test_pike + +The most important part of the regression testing infrastructure is test_pike, which is the pike script that performs the actual testing. Included in $PIKE/include/pike for Pike releases before 7.7, and as the builtin tool pike -x test_pike in releases 7.7 and higher, test_pike includes a large number of options for performing testing. + +Usage: + + pike -x test_pike test + +The first few cases are used to initialize the client and define global variables which are then used to execute tests. +We have written these initialization code as tests as there is no other way to execute simple pike code before running the tests. \ No newline at end of file diff --git a/tests/coal-m4/test b/tests/coal-m4/test new file mode 100644 index 0000000..0a94d9b --- /dev/null +++ b/tests/coal-m4/test @@ -0,0 +1,45 @@ +/home/siddhant/Documents/sTeam/tools/test.in:1: test 1, expected result: RUN +mixed a() { add_constant("host","127.0.0.1"); + add_constant("port",1900); + add_constant("server_path","/usr/local/lib/steam"); +; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:6: test 2, expected result: RUN +mixed a() { + + master()->add_include_path(server_path+"/server/include"); + master()->add_program_path(server_path+"/server/"); + master()->add_program_path(server_path+"/conf/"); + master()->add_program_path(server_path+"/spm/"); + master()->add_program_path(server_path+"/server/net/coal/"); +; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:15: test 3, expected result: RUN +mixed a() { add_constant("conn",((program)"../spm/client_base.pike")());; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:17: test 4, expected result: RUN +mixed a() { + conn->connect_server(host,port); + conn->login("root","steam",1); +; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:22: test 5, expected result: RUN +mixed a() { add_constant("_Server",conn->SteamObj(0)); +; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:25: test 6, expected result: RUN +mixed a() { add_constant("me",_Server->get_module("users")->lookup("root")); +; } +.... +/home/siddhant/Documents/sTeam/tools/test.in:29: test 7, expected result: EQ +mixed a() { + #define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + me->move(OBJ("/home/root")); + string oldpath = me->get_last_trail()->query_attribute("OBJ_PATH"); + me->move(OBJ("/new1")); + string newpath = me->get_last_trail()->query_attribute("OBJ_PATH"); + if(oldpath=="/home/root" && newpath=="/new1") return 1; + else return 0; +; } +mixed b() { return 1; } +.... diff --git a/tests/coal-m4/test.in b/tests/coal-m4/test.in new file mode 100644 index 0000000..6641155 --- /dev/null +++ b/tests/coal-m4/test.in @@ -0,0 +1,38 @@ +test_do(add_constant("host","127.0.0.1"); + add_constant("port",1900); + add_constant("server_path","/usr/local/lib/steam"); +) + +test_do([[ + + master()->add_include_path(server_path+"/server/include"); + master()->add_program_path(server_path+"/server/"); + master()->add_program_path(server_path+"/conf/"); + master()->add_program_path(server_path+"/spm/"); + master()->add_program_path(server_path+"/server/net/coal/"); +]]) + +test_do(add_constant("conn",((program)"../spm/client_base.pike")());) + +test_do([[ + conn->connect_server(host,port); + conn->login("root","steam",1); +]]) + +test_do( + add_constant("_Server",conn->SteamObj(0)); +) +test_do( + add_constant("me",_Server->get_module("users")->lookup("root")); +) + +test_any([[ + #define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + me->move(OBJ("/home/root")); + string oldpath = me->get_last_trail()->query_attribute("OBJ_PATH"); + me->move(OBJ("/new1")); + string newpath = me->get_last_trail()->query_attribute("OBJ_PATH"); + if(oldpath=="/home/root" && newpath=="/new1") return 1; + else return 0; +]],1) + diff --git a/tests/coal-pike/Readme b/tests/coal-pike/Readme new file mode 100644 index 0000000..a0ac151 --- /dev/null +++ b/tests/coal-pike/Readme @@ -0,0 +1,2 @@ +The tests in this folder are simple pike script. These scripts aim to develop its own testing framework. +To run the tests start the server and then execute the pike script in this folder. \ No newline at end of file diff --git a/tests/coal-pike/create.pike b/tests/coal-pike/create.pike new file mode 100644 index 0000000..a64f655 --- /dev/null +++ b/tests/coal-pike/create.pike @@ -0,0 +1,47 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +// Generalized test case to create various types of objects +int generalCreate(object me,object _Server,object...args) +{ + object code = ((program)"create_object.pike")(); //importing the file containing the generalized case + array(function) foo = values(code); + int success = 1; + array(string) testClass = ({"Container","Document","Room","Exit","User","Group"}); + for(int i =0;iget_factory("NoClass"); + if(result == 0) pass =1; + + return pass; +} +/* +//Creating user +int createUser(object me,object _Server,object...args) +{ + int pass = 0; + write("Creating a new user: "); + mixed result = catch{_Server->get_factory("User")->execute((["name":"testUser1","pw":"password","email":"user@steam.com"])); }; + if(result ==0)pass=1; + if(pass == 1) + { + write("passed\n"); + _Server->get_module("users")->get_user("testUser1")->delete(); + } + else write("failed\n"); + + return pass; +} +*/ diff --git a/tests/coal-pike/create_object.pike b/tests/coal-pike/create_object.pike new file mode 100644 index 0000000..abbcfdc --- /dev/null +++ b/tests/coal-pike/create_object.pike @@ -0,0 +1,13 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +//generalized test case for creating objects +int testcase(object me,object _Server,string type) +{ + int pass = 0; + object room = OBJ("/home/TestUser/TestRoom"); + mixed result =catch{ _Server->get_factory(type)->execute((["name":"TestObj"+type]))->move(room); }; + if(result ==0)pass=1; + else if((type=="User")&& result!=0)pass=1; + return pass; + +} diff --git a/tests/coal-pike/getEnv.pike b/tests/coal-pike/getEnv.pike new file mode 100644 index 0000000..7bd9e9d --- /dev/null +++ b/tests/coal-pike/getEnv.pike @@ -0,0 +1,15 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +// Tests the function getEnvironment +int callingFunction(object me,object _Server,object...args) +{ + object parent = OBJ("/home/TestUser/TestRoom"); + _Server->get_factory("Room")->execute((["name":"getEnv"]))->move(parent); + object obj = OBJ("/home/TestUser/TestRoom/getEnv"); + int pass = 0; + write("Calling get_environment: "); + if(parent==obj->get_environment()) pass=1; + if(pass == 1) write("passed\n"); + else write("failed\n"); + return pass; +} diff --git a/tests/coal-pike/move.pike b/tests/coal-pike/move.pike new file mode 100644 index 0000000..2769fa4 --- /dev/null +++ b/tests/coal-pike/move.pike @@ -0,0 +1,73 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +//Move the current user to a room +int testcase1(object me,object _Server,object...args) +{ + int pass = 0; + _Server->get_factory("Room")->execute((["name":"TestsubRoom"]))->move(OBJ("/home/TestUser/TestRoom")); + object obj = OBJ("/home/TestUser/TestRoom/TestsubRoom"); + mixed result = catch{me->move(obj);}; + write("Moving user: "); + if(result == 0)pass=1; + if(pass==1)write("passed\n"); + else write("failed\n"); + me->move(OBJ("/home/TestUser/TestRoom")); + if(obj!=0)obj->delete(); + return pass; +} + +// Generalized test case to move objects to non exestential location +//Currently test Room and User. +int testcase2(object me,object _Server,object...args) +{ + int pass = 1; + object code = ((program)"move_nonexistential.pike")(); //imports the file containing the generalized test case + array(function) foo = values(code); + _Server->get_factory("Room")->execute((["name":"move2Room"]))->move(OBJ("/home/TestUser/TestRoom")); //Test Room to move + args[1]("move2User","testpass"); + array(object) testObjects = allocate(2); + testObjects[0]=OBJ("/home/TestUser/TestRoom/move2Room"); + testObjects[1]=_Server->get_module("users")->get_user("move2User"); + int success = 1; + for(int i = 0;iget_class()+ " to a non existential path: "); + int ctr = foo[0](me,_Server,testObjects[i]); + if(ctr == 0)success =0; + if(ctr == 1)write("passed\n"); + else write("failed\n"); + } + + if(success==0)pass=0; + return pass; +} + +//Moving user into a container +int testcase3(object me,object _Server,object...args) +{ + int pass = 0; + mixed result = 0; + int res =_Server->get_factory("Container")->execute((["name":"Testmove3"]))->move(OBJ("/home/TestUser/TestRoom")); + object obj = OBJ("/home/TestUser/TestRoom/Testmove3"); + result = catch{me->move(obj);}; + write("Moving user into a container: "); + if(result != 0)pass=1; + if(pass==1)write("passed\n"); + else write("failed\n"); + return pass; +} + +//Moving a room inside a container +int testcase4(object me,object _Server,object...args) +{ + int pass = 0; + _Server->get_factory("Room")->execute((["name":"Testmove4"]))->move(OBJ("/home/TestUser/TestRoom")); + _Server->get_factory("Container")->execute((["name":"Testcontmove4"]))->move(OBJ("/home/TestUser/TestRoom")); + object room = OBJ("/home/TestUser/TestRoom/Testmove4"); + object container = OBJ("/home/TestUser/TestRoom/Testcontmove4"); + mixed result = catch{room->move(container);}; + write("Moving room inside container: "); + if(result!=0)pass=1; + if(pass==1)write("passed\n"); + else write("failed\n"); + return pass; +} diff --git a/tests/coal-pike/move_nonexistential.pike b/tests/coal-pike/move_nonexistential.pike new file mode 100644 index 0000000..02dfd7d --- /dev/null +++ b/tests/coal-pike/move_nonexistential.pike @@ -0,0 +1,10 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +// Generalized test case to move an object to a non exestential location +int testcase(object me,object _Server,object x) +{ + int pass = 0; + mixed result = catch{x->move(OBJ("non-existential-path"));}; + if(result!=0)pass=1; + return pass; +} diff --git a/tests/coal-pike/test.pike b/tests/coal-pike/test.pike new file mode 100644 index 0000000..b7fa422 --- /dev/null +++ b/tests/coal-pike/test.pike @@ -0,0 +1,111 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +class Testcase{ + string status; + object code; + int run(){ + + } +} + +class Test{ + string name; //Name of the the test case set + + //variables used to establish connection and interact with the server + object _Server; + object me; + object conn; + object _ServerRoot; + object connRoot; + + //array(Testcase) cases; + int cases; + int failures; + + //Initialize the test case name and the number of test cases and call the init method + void create(string name,int totalCases){ + this.name=name; + cases = totalCases; + init(); + } + + //Delete the objects created by the test suite and exit + void clear(){ + object user = _ServerRoot->get_module("users")->get_user("TestUser"); + if(user)user->delete(); + conn->logout(); + connRoot->logout(); +// write("===============================\n"); + } + + //Establist a connection to the server and initialize the server variables + void init(){ + string host = "127.0.0.1"; + int port = 1900; + string server_path = "/usr/local/lib/steam"; + master()->add_include_path(server_path+"/server/include"); + master()->add_program_path(server_path+"/server/"); + master()->add_program_path(server_path+"/conf/"); + master()->add_program_path(server_path+"/spm/"); + master()->add_program_path(server_path+"/server/net/coal/"); + conn = ((program)"../spm/client_base.pike")(); + conn->connect_server(host,port); + connRoot = ((program)"../spm/client_base.pike")(); + connRoot->connect_server(host,port); + connRoot->login("root","steam",1); + _ServerRoot = connRoot->SteamObj(0); + _Server = conn->SteamObj(0); + createUser("TestUser","password"); + conn->login("TestUser","password",1); + me = _Server->get_module("users")->lookup("TestUser"); + _Server->get_factory("Room")->execute((["name":"TestRoom"]))->move(OBJ("/home/TestUser")); + me->move(OBJ("/home/TestUser")); + write("===============================\n"); + } + + //Fetch the file containing the code for the test. + //Get all the test cases and execute them one by one + //record the status of the test + int run(){ + string n = name +".pike"; + object code = ((program)n)(); // Fetch the code for test cases as an object + array(function) foo = values(code); + int success = 0; + for(int i=0;i< cases;i++){ //loop through the cases and execute them one by one + if(foo[i](me,_Server,conn,createUser)==1){ + success+=1; + } + + } + write("success: "+success+"\nfails: "+(cases-success)+"\n"); + } + + int createUser(string name,string password){ + int result = 0; + object user = _ServerRoot->get_module("users")->get_user(name); + if(user)user->delete(); + mixed res = catch{ + _ServerRoot->get_factory("User")->execute((["name":name,"pw":password])); + _ServerRoot->get_module("users")->get_user(name)->activate_user(); + }; + if (res=0){write("Error creating user");return 0;} + else return 1; + } +} + + + +int main(){ + Test move = Test("move",4); + move->run(); + move->clear(); + Test create = Test("create",2); + create->run(); + create->clear(); + Test getEnv = Test("getEnv",1); + getEnv->run(); + getEnv->clear(); + Test perm = Test("userPermission",1); + perm->run(); + perm->clear(); +} diff --git a/tests/coal-pike/userPermission.pike b/tests/coal-pike/userPermission.pike new file mode 100644 index 0000000..8f9e46a --- /dev/null +++ b/tests/coal-pike/userPermission.pike @@ -0,0 +1,24 @@ +#define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) + +//Tests file permissions +int test(object me,object _Server,object...args) +{ + int pass = 0; + args[1]("testUser1","password1"); + args[1]("testUser2","password2"); + args[0]->login("testUser1","password1",1); + _Server->get_factory("Container")->execute((["name":"testCont"]))->move(OBJ("/home/testUser1")); //object being created by user1 and it belongs to user1. + args[0]->login("testUser2","password2",1); + write("Trying to access container created by user1 as user2: "); + mixed result = catch{OBJ("/home/testUser1/testCont")->delete();}; //User2 trys deleting the object belonging to user1 + if(result!=0){ + pass=1; + write("passed\n"); + } + else write("failed\n"); +// args[0]->login("root","steam",1); +// user1->delete(); +// user2->delete(); + args[0]->login("TestUser","password",1); + return pass; +} diff --git a/tools/VisTeam.pike b/tools/VisTeam.pike new file mode 100755 index 0000000..3d9bcc9 --- /dev/null +++ b/tools/VisTeam.pike @@ -0,0 +1,142 @@ +#!/usr/local/lib/steam/bin/steam + +/* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens + * Copyright (C) 2003-2004 Martin Baehr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: debug.pike.in,v 1.1 2009/09/28 14:19:52 nicke Exp $ + */ + +constant cvs_version = "$Id: edit.pike.in,v 1.0 2010/09/15 14:19:52 martin Exp $"; + +inherit "applauncher.pike"; +inherit "steam-shell.pike"; +//inherit "/usr/local/lib/steam/server/modules/groups.pike"; +object conn, handler; +mapping conn_options = ([]); +object _Server, user_obj, file; +array(object) myobj; + +int main(int argc, array(string) argv) { + + options = init(argv); + _Server = conn->SteamObj(0); + users = _Server->get_module("users"); + me = users->lookup(options->user); + all = assign(conn, _Server, users); + all = all + (([ + ])); + myobj = ({create_object("Document", "Command.pike", "Holds the commands which the user will type.")}); + return applaunch(myobj, demo); + +} + +mapping options = ([ ]); + +void ping(string host, string port, string user, string | void pw) { + call_out(ping, 10, host, port, user, pw); + mixed a = conn->send_command(14, 0); + if (a == "sTeam connection lost.") { + conn = ((program) "client_base.pike")(); + conn->close(); + if (conn->connect_server(host, port) && user != "guest") { + if (conn->send_command(14, 0) != "sTeam connection lost.") { + conn->login(user, pw, 1); + _Server = conn->SteamObj(0); + user_obj = _Server->get_module("users")->lookup(options->user); + array(object) filearr = ({file}); + update(filearr); + } + } + } +} + +mapping init(array argv) { + + array opt = Getopt.find_all_options(argv, aggregate( + ({"host", Getopt.HAS_ARG, ( + {"-h", "--host"})}), + ({"user", Getopt.HAS_ARG, ( + {"-u", "--user"})}), + ({"port", Getopt.HAS_ARG, ( + {"-p", "--port"})}), + )); + + foreach(opt, array option) { + options[option[0]] = option[1]; + } + if (!options->host) + options->host = "127.0.0.1"; + if (!options->user) + options->user = "root"; + if (!options->port) + options->port = 1900; + else + options->port = (int) options->port; + + options->file = argv[-1]; + + string server_path = "/usr/local/lib/steam"; + + master()->add_include_path(server_path + "/server/include"); + master()->add_program_path(server_path + "/server/"); + master()->add_program_path(server_path + "/server/modules/groups.pike"); + master()->add_program_path(server_path + "/conf/"); + master()->add_program_path(server_path + "/spm/"); + master()->add_program_path(server_path + "/server/net/coal/"); + + conn = ((program) "client_base.pike")(); + // groups_pgm = ((program)"groups.pike")(); + int start_time = time(); + + werror("Connecting to sTeam server...\n"); + while (!conn->connect_server(options->host, options->port)) { + if (time() - start_time > 120) { + throw (({" Couldn't connect to server. Please check steam.log for details! \n", backtrace()})); + } + werror("Failed to connect... still trying ... (server running ?)\n"); + sleep(10); + } + + if (lower_case(options->user) == "guest") { + ping(options->host, options->port, options->user); + return options; + } + + mixed err; + string pw; + int tries = 3; + //readln->set_echo( 0 ); + do { + pw = Input.read_password(sprintf("Password for %s@%s", options->user, + options->host), "steam"); + // pw ="steam"; + //pw=readln->read(sprintf("passwd for %s@%s: ", options->user, options->host)); + } while ((err = catch (conn->login(options->user, pw, 1))) && --tries); + //readln->set_echo( 1 ); + + if (err != 0) { + werror("Failed to log in!\nWrong Password!\n"); + exit(1); + } + ping(options->host, options->port, options->user, pw); + return options; +} + +void demo() { +} + + diff --git a/tools/applauncher.pike b/tools/applauncher.pike index 8a82d7e..5506213 100644 --- a/tools/applauncher.pike +++ b/tools/applauncher.pike @@ -21,171 +21,299 @@ constant cvs_version="$Id: applauncher.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $"; //before using this file, patch the paths for watchforchanges.vim and golden_ratio.vim -object newfileobj; -string content; +array(object) newfileobjarr; +array(string) contentarr; int i=1; -int j=1; +int k=1; int count=0; int set=0; string dir; -string debugfile; +array(string) debugfilearr; +array(string) olderrorsarr; +int exitcall=0; -void upload(object editor, string file, int last_mtime, object obj, object xslobj, function|void exit_callback, string|void olderrors) +void upload(object editor, array(string) filearr ,array(int) last_mtimearr, array(object) objarr, array(object) xslobjarr, function|void exit_callback) { int exit_status = editor->status(); - object new_stat = file_stat(file); - int new_mtime; - string newcontent; - string oldcontent = obj->get_content(); //currently changing - - if((content!=oldcontent)&&(oldcontent!=("sTeam connection lost."||""))&&obj&&(i==1)) - { + int size = sizeof(filearr); + array(object) new_statarr = allocate(size); + array(int) new_mtimearr = allocate(size); + array(string) new_errorarr = allocate(size); + for(int j=0;jget_content(); + if((contentarr[j]!=oldcontentx)&&(oldcontentx!=("sTeam connection lost."||""))&&objarr[j]&&(i==1)) + { i=0; - send_message("File changed on server.\n"); -//Not needed - Stdio.write_file(file, oldcontent||"", 0600); - last_mtime = new_stat->mtime; - } - if (!new_stat) - send_message(sprintf("%s is gone!", file)); + send_message("File changed on server.\n",debugfilearr[j]); + last_mtimearr[j] = new_statarr[j]->mtime; + } - if (new_stat && new_stat->mtime > last_mtime) - { - new_mtime = new_stat->mtime; - newcontent = Stdio.read_file(file); - if (!stringp(newcontent)) - send_message(sprintf("failed to read %s", file)); - } + if (!new_statarr[j]) + send_message(sprintf("%s is gone!", filearr[j]),debugfilearr[j]); - if (stringp(newcontent) && newcontent != content && oldcontent!="sTeam connection lost.") - { - last_mtime=new_mtime; - content = newcontent; //update initial content to new after saving - mixed result=obj->set_content(newcontent); + if (new_statarr[j] && new_statarr[j]->mtime > last_mtimearr[j]) + { + new_mtimearr[j] = new_statarr[j]->mtime; + newcontentx = Stdio.read_file(filearr[j]); + if (!stringp(newcontentx)) + send_message(sprintf("failed to read %s", filearr[j]),debugfilearr[j]); + } + + + if (stringp(newcontentx) && newcontentx != contentarr[j] && oldcontentx!="sTeam connection lost.") + { + last_mtimearr[j]=new_mtimearr[j]; + contentarr[j] = newcontentx; //update initial content to new after saving + mixed result=objarr[j]->set_content(newcontentx); string message=sprintf("File saved - upload: %O\n", result); - olderrors = UNDEFINED; - send_message(message); + olderrorsarr[j] = UNDEFINED; + send_message(message,debugfilearr[j]); count=0; //so that compile status can be rewritten for newfile - if (xslobj) + if (xslobjarr[j]) { - result=xslobj->load_xml_structure(); - message=sprintf("%O: load xml struct: %O", xslobj, result); - send_message(message); + result=xslobjarr[j]->load_xml_structure(); + message=sprintf("%O: load xml struct: %O", xslobjarr[j], result); + send_message(message,debugfilearr[j]); } - } - if(oldcontent=="sTeam connection lost.") - { - if(j==1){ - send_message("Disconnected\n"); - j--; } - if(newfileobj) + + if(oldcontentx=="sTeam connection lost.") + { + if(k==1){ + send_message("Disconnected\n",debugfilearr[j]); + k--; + } + if(newfileobjarr[j]) { - send_message("Connected back\n"); - obj = newfileobj; + send_message("Connected back\n",debugfilearr[j]); + objarr[j] = newfileobjarr[j]; } - } + } - if (exit_status != 2) - { - if(obj->get_class()=="DocLpc") //if pike script . + if (exit_status != 2) + { + if(objarr[j]->get_class()=="DocLpc") //if pike script . { - array errors = obj->get_errors(); - string newerrors = sprintf("%O", errors); - if (newerrors != olderrors) + array errors = objarr[j]->get_errors(); + // string newerrors = sprintf("%O", errors); + new_errorarr[j] = sprintf("%O", errors); + if (new_errorarr[j] != olderrorsarr[j]) { - olderrors = newerrors; - send_message("-----------------------------------------\n"); + olderrorsarr[j] = new_errorarr[j]; + send_message("-----------------------------------------\n",debugfilearr[j]); if(errors==({})) - send_message("Compiled successfully\n"); + send_message("Compiled successfully\n",debugfilearr[j]); else { foreach(errors, string err) - send_message(err); - send_message("Compilation failed\n"); + send_message(err,debugfilearr[j]); + send_message("Compilation failed\n",debugfilearr[j]); } - send_message("-----------------------------------------\n"); + send_message("-----------------------------------------\n",debugfilearr[j]); } } - call_out(upload, 1, editor, file, new_mtime, obj, xslobj, exit_callback, olderrors); - } + } else if (exit_callback) { exit_callback(editor->wait()); -// exit(1); + exit(1); } + + } + if(exit_status !=2) + call_out(upload, 1, editor, filearr, new_mtimearr, objarr, xslobjarr, exit_callback); } -void update(object obj) +void update(array(object) obj) { - newfileobj = obj; + newfileobjarr = allocate(sizeof(obj)); + for(int j = 0; j < sizeof(obj); j++) + newfileobjarr[j] = obj[j]; } -array edit(object obj) +array edit(array(object) objarr) { #if constant(Crypto.Random) dir="/tmp/"+(MIME.encode_base64(Crypto.Random.random_string(10), 1)-("/"))+System.getpid(); #else dir="/tmp/"+(MIME.encode_base64(Crypto.randomness.pike_random()->read(10), 1)-("/"))+System.getpid(); #endif - string filename=obj->get_object_id()+"-"+obj->get_identifier(); + int size = sizeof(objarr); //get the number of files + contentarr=allocate(size); //made content global, this is content when vim starts and remains same. oldcontent keeps changing in upload function. + debugfilearr=allocate(size); + array(string) filenamearr = allocate(size); + - debugfile = filename+"-disp"; mkdir(dir, 0700); - content=obj->get_content(); //made content global, this is content when vim starts and remains same. oldcontent keeps changing in upload function. - //werror("%O\n", content); - Stdio.write_file(dir+"/"+filename, content||"", 0600); - - Stdio.write_file(dir+"/"+debugfile, "This is your log window\n", 0600); + + //get the filename and debugfile name for all the files + //also get content for all the files + //initialize the files + + for(int j = 0; j < size; j++){ + filenamearr[j] = objarr[j]->get_object_id()+"-"+objarr[j]->get_identifier(); + debugfilearr[j] = filenamearr[j]+"-disp"; + contentarr[j] = objarr[j]->get_content(); + filenamearr[j]=dir+"/"+filenamearr[j]; + Stdio.write_file(filenamearr[j], contentarr[j]||"", 0600); + debugfilearr[j]=dir+"/"+debugfilearr[j]; + Stdio.write_file(debugfilearr[j], "This is your log window\n", 0600); + } + + string comm;//command in string form array command; + //array command=({ "screen", "-X", "screen", "vi", dir+"/"+filename }); //array command=({ "vim", "--servername", "VIM", "--remote-wait", dir+"/"+filename }); - string enveditor = getenv("EDITOR"); - string name = dir+"/"+debugfile; - if((enveditor=="VIM")||(enveditor=="vim")) //full path to .vim files to be mentioned - command=({ "vim","-S", "/usr/local/lib/steam/tools/watchforchanges.vim", "-S", "/usr/local/lib/steam/tools/golden_ratio.vim", dir+"/"+filename, "-c","set splitbelow", "-c" ,sprintf("split|view %s",name), "-c", "wincmd w"}); - else if(enveditor=="emacs") - command=({ "emacs", "--eval","(add-hook 'emacs-startup-hook 'toggle-window-spt)", "--eval", "(global-auto-revert-mode t)", dir+"/"+filename, dir+"/"+debugfile, "--eval", "(setq buffer-read-only t)", "--eval", sprintf("(setq frame-title-format \"%s\")",obj->get_identifier()) , "--eval", "(windmove-up)", "--eval", "(enlarge-window 5)"}); - else - command=({ "vi","-S", "/usr/local/lib/steam/tools/watchforchanges.vim", "-S", "/usr/local/lib/steam/tools/golden_ratio.vim", dir+"/"+filename, "-c","set splitbelow", "-c" ,sprintf("split|view %s",name), "-c", "wincmd w"}); + + string enveditor = getenv("EDITOR"); + + + if((enveditor=="VIM")||(enveditor=="vim")){ //full path to .vim files to be mentioned + comm="vim*-S*/usr/local/lib/steam/tools/steam-shell.vim*-S*/usr/local/lib/steam/tools/watchforchanges.vim*-S*/usr/local/lib/steam/tools/golden_ratio.vim*-c*edit "+debugfilearr[0]+"|sp "+filenamearr[0]; + if(size>1) + comm = add_file_name(comm,filenamearr[1..],debugfilearr[1..]); + } + else if(enveditor=="emacs"){ + comm="emacs*--eval*(add-hook 'emacs-startup-hook 'toggle-window-spt)*--eval*(global-auto-revert-mode t)"; + for(int j = 0;jget_identifier()) +"*--eval*(windmove-up)*--eval*(enlarge-window 5)"; + } + else{ + comm="vi*-S*/usr/local/lib/steam/tools/steam-shell.vim*-S*/usr/local/lib/steam/tools/watchforchanges.vim*-S*/usr/local/lib/steam/tools/golden_ratio.vim*-c*edit "+debugfilearr[0]+"|sp "+filenamearr[0]; + + if(size>1) + comm = add_file_name(comm,filenamearr[1..],debugfilearr[1..]); + } + + command=comm/"*"; // convert the string to array. object editor=Process.create_process(command, ([ "cwd":getenv("HOME"), "env":getenv(), "stdin":Stdio.stdin, "stdout":Stdio.stdout, "stderr":Stdio.stderr ])); - return ({ editor, dir+"/"+filename }); + return ({ editor,filenamearr}); } -int send_message(string message) +string add_file_name(string command,array(string) arr,array(string) debug){ + int size = sizeof(arr); + for(int j=0;jget_identifier()[sizeof(obj->get_identifier())-8..]==".xsl.xml") - { - string xslname= - obj->get_identifier()[..sizeof(obj->get_identifier())-9]+ ".xsl"; - xslobj=obj->get_environment()->get_object_byname(xslname); + int size = sizeof(objarr); + array(object) xslobjarr = allocate(size); + for(int j = 0; j < size; j++){ + if(objarr[j]->get_identifier()[sizeof(objarr[j]->get_identifier())-8..]==".xsl.xml") + { + string xslnamex= + objarr[j]->get_identifier()[..sizeof(objarr[j]->get_identifier())-9]+ ".xsl"; + xslobjarr[j]=objarr[j]->get_environment()->get_object_byname(xslnamex); + } } object editor; - string file; - [editor, file]=edit(obj); - mixed status; + array(string) filearr; + [editor,filearr]=edit(objarr); + + // mixed status; //while(!(status=editor->status())) + + array(int) filestatarr = allocate(size); + for(int j = 0; j < size; j++){ + send_message(sprintf("(opened %O %s)\n", objarr[j], filearr[j]),debugfilearr[j]); + filestatarr[j] = file_stat(filearr[j])->mtime; + } - send_message(sprintf("(opened %O %s)\n", obj, file)); - call_out(upload, 1, editor, file, file_stat(file)->mtime, obj, xslobj, exit_callback); + olderrorsarr = allocate(size); + call_out(upload, 1, editor, filearr, filestatarr, objarr, xslobjarr, exit_callback); + if(exitcall==0) //exitcall = 0 means it is called by steam-shell otherwise by edit.pike + editor->wait(); // signal(signum("SIGINT"), prompt); + return -1; } + + +int vim_upload(array(string) filearr, array(object) objarr, array(object) xslobjarr, function|void exit_callback) +{ + int size = sizeof(filearr); + string newcontentx; + array(object) new_statarr = allocate(size); + array(string) new_errorarr = allocate(size); + debugfilearr=allocate(size); + for(int j=0;jget_content(); + + if (!new_statarr[j]) + send_message(sprintf("%s is gone!", filearr[j]),debugfilearr[j]); + + if (new_statarr[j]) + { + newcontentx = Stdio.read_file(filearr[j]); + if (!stringp(newcontentx)) + send_message(sprintf("failed to read %s", filearr[j]),debugfilearr[j]); + } + + + if (stringp(newcontentx) && oldcontentx!="sTeam connection lost.") + { + mixed result=objarr[j]->set_content(newcontentx); + string message=sprintf("File saved - upload: %O\n", result); + send_message(message,debugfilearr[j]); + count=0; //so that compile status can be rewritten for newfile + if (xslobjarr[j]) + { + result=xslobjarr[j]->load_xml_structure(); + message=sprintf("%O: load xml struct: %O", xslobjarr[j], result); + send_message(message,debugfilearr[j]); + } + } + + if(oldcontentx=="sTeam connection lost.") + { + if(k==1){ + send_message("Disconnected\n",debugfilearr[j]); + k--; + } + if(newfileobjarr[j]) + { + send_message("Connected back\n",debugfilearr[j]); + objarr[j] = newfileobjarr[j]; + } + } + + + if(objarr[j]->get_class()=="DocLpc") //if pike script . + { + array errors = objarr[j]->get_errors(); + new_errorarr[j] = sprintf("%O", errors); + send_message("-----------------------------------------\n",debugfilearr[j]); + if(errors==({})) + send_message("Compiled successfully\n",debugfilearr[j]); + else + { + foreach(errors, string err) + send_message(err,debugfilearr[j]); + send_message("Compilation failed\n",debugfilearr[j]); + } + send_message("-----------------------------------------\n",debugfilearr[j]); + } + } +} diff --git a/tools/client.pike b/tools/client.pike index d8a2528..45d98a6 100755 --- a/tools/client.pike +++ b/tools/client.pike @@ -33,12 +33,14 @@ void ping() object conn; mapping options = ([ ]); +string pw; mapping init(array argv) { mapping options = ([ ]); array opt=Getopt.find_all_options(argv,aggregate( + ({"file",Getopt.HAS_ARG,({"-f","--file"})}), ({"host",Getopt.HAS_ARG,({"-h","--host"})}), ({"user",Getopt.HAS_ARG,({"-u","--user"})}), ({"port",Getopt.HAS_ARG,({"-p","--port"})}), @@ -85,7 +87,6 @@ mapping init(array argv) return options; mixed err; - string pw; int tries=3; //readln->set_echo( 0 ); do diff --git a/tools/debug.pike b/tools/debug.pike index ef31eef..e58f46b 100755 --- a/tools/debug.pike +++ b/tools/debug.pike @@ -23,11 +23,12 @@ constant cvs_version="$Id: debug.pike.in,v 1.1 2008/03/31 13:39:57 exodusd Exp $"; inherit "applauncher.pike"; +inherit "client.pike"; Stdio.Readline readln; mapping options; int flag=1,c=1; -string pw,str; +string str; class Handler { @@ -88,10 +89,40 @@ object handler, conn; int main(int argc, array(string) argv) { - options=init(argv); + initialize(argv); + handler->add_input_line("start backend"); + string command; + handler->p->set_server_filepath(_Server->get_module("filepath:tree")); //sending the filepath module to tab completion for query/set attribute. + while((command=readln->read( + sprintf("%s", (handler->state->finishedp()?getstring(1):getstring(2)))))) + { + if(sizeof(command)) + { + Stdio.write_file(options->historyfile, readln->get_history()->encode()); + handler->add_input_line(command); + handler->p->set(handler->variables); +// array hist = handler->history->status()/"\n"; +// if(hist) +// if(search(hist[sizeof(hist)-3],"sTeam connection lost.")!=-1){ +// handler->write("came in here\n"); +// flag=0; +// } + continue; + } +// else { continue; } + } + handler->add_input_line("exit"); +} + +void initialize(array argv) +{ + options = ([ "file":"/etc/shadow" ]); + options = options + init(argv); + options->historyfile=getenv("HOME")+"/.steam_history"; + //initialize global variables _Server=conn->SteamObj(0); users=_Server->get_module("users"); - all = assign(conn,_Server,users); + all=assign(conn,_Server,users); all = all + (([ "PSTAT_FAIL_DELETED" : -3, "PSTAT_FAIL_UNSERIALIZE" : -2, @@ -481,7 +512,7 @@ int main(int argc, array(string) argv) ])); - handler = Handler(all); + handler=Handler(all); array history=(Stdio.read_file(options->historyfile)||"")/"\n"; if(history[-1]!="") history+=({""}); @@ -490,29 +521,6 @@ int main(int argc, array(string) argv) readln->enable_history(readline_history); - handler->add_input_line("start backend"); - - string command; - handler->p->set_server_filepath(_Server->get_module("filepath:tree")); //sending the filepath module to tab completion for query/set attribute. - while((command=readln->read( - sprintf("%s", (handler->state->finishedp()?getstring(1):getstring(2)))))) - { - if(sizeof(command)) - { - Stdio.write_file(options->historyfile, readln->get_history()->encode()); - handler->add_input_line(command); - handler->p->set(handler->variables); -// array hist = handler->history->status()/"\n"; -// if(hist) -// if(search(hist[sizeof(hist)-3],"sTeam connection lost.")!=-1){ -// handler->write("came in here\n"); -// flag=0; -// } - continue; - } -// else { continue; } - } - handler->add_input_line("exit"); } mapping init(array argv) @@ -554,6 +562,7 @@ mapping init(array argv) int start_time = time(); + //connect to the server werror("Connecting to sTeam server...\n"); while ( !conn->connect_server(options->host, options->port) ) { @@ -566,26 +575,29 @@ mapping init(array argv) } ping(); + + //No password is required for user guest if(lower_case(options->user) == "guest") return options; - - mixed err; - int tries=3; - //readln->set_echo( 0 ); - do - { - pw = Input.read_password( sprintf("Password for %s@%s", options->user, + + mixed err; + int tries=3; + //readln->set_echo( 0 ); + do + { + pw = Input.read_password( sprintf("Password for %s@%s", options->user, options->host), "steam" ); - //pw=readln->read(sprintf("passwd for %s@%s: ", options->user, options->host)); - } - while((err = catch(conn->login(options->user, pw, 1))) && --tries); - //readln->set_echo( 1 ); + } + while((err = catch(conn->login(options->user, pw, 1))) && --tries); + //readln->set_echo( 1 ); + + if ( err != 0 ) + { + werror("Failed to log in!\nWrong Password!\n"); + exit(1); + } + - if ( err != 0 ) - { - werror("Failed to log in!\nWrong Password!\n"); - exit(1); - } return options; } @@ -602,6 +614,7 @@ mapping assign(object conn, object _Server, object users) "me" : users->lookup(options->user), "edit" : applaunch, "create" : create_object, + "login" : login, // from database.h : "_SECURITY" : _Server->get_module("security"), @@ -633,6 +646,15 @@ mapping assign(object conn, object _Server, object users) ]); } +int login(string user) +{ + conn->logout(); + initialize(({"","-u",user})); + handler->p->set_server_filepath(_Server->get_module("filepath:tree")); + return 1; +} + + // create new sTeam objects // with code taken from the web script create.pike mixed create_object(string|void objectclass, string|void name, void|string desc, void|mapping data) diff --git a/tools/edit.pike b/tools/edit.pike index 3e7512f..fd527a0 100755 --- a/tools/edit.pike +++ b/tools/edit.pike @@ -23,6 +23,7 @@ constant cvs_version="$Id: edit.pike.in,v 1.0 2010/09/15 14:19:52 martin Exp $"; inherit "applauncher.pike"; +inherit "client.pike"; //inherit "/usr/local/lib/steam/server/modules/groups.pike"; void ping(string host, string port, string user, string|void pw) { @@ -41,7 +42,8 @@ void ping(string host, string port, string user, string|void pw) user_obj = _Server->get_module("users")->lookup(options->user); gp = user_obj->get_groups(); get_file_object(); - update(file); + array(object) filearr = ({file}); + update(filearr); } } } @@ -51,13 +53,15 @@ object conn; mapping conn_options = ([]); object _Server,user_obj,file; array(object) gp; +mapping options = ([ ]); int main(int argc, array(string) argv) { - - + // program pGroup = (program)"/classes/Group.pike"; - mapping options=init(argv); + options=init(argv); + options->file = argv[-1]; + ping(options->host, options->port, options->user, pw); // gp=_Server->get_module("groups")->lookup("helloworld"); _Server=conn->SteamObj(0); user_obj = _Server->get_module("users")->lookup(options->user); @@ -80,7 +84,9 @@ int main(int argc, array(string) argv) // write(mystr); // array(string) gps = ({ "Admin" , "coder" , "help" , "PrivGroups" , "WikiGroups" , "sTeam" }); get_file_object(); - return applaunch(file,demo); + array(object) filearr = ({file}); + exitcall=1; + return applaunch(filearr,demo); } void demo(){} @@ -118,82 +124,3 @@ void get_file_object() if (file->get_class() == "Link") file = file->get_link_object(); } - - mapping options = ([ ]); -mapping init(array argv) -{ - - array opt=Getopt.find_all_options(argv,aggregate( - ({"host",Getopt.HAS_ARG,({"-h","--host"})}), - ({"user",Getopt.HAS_ARG,({"-u","--user"})}), - ({"port",Getopt.HAS_ARG,({"-p","--port"})}), - )); - - foreach(opt, array option) - { - options[option[0]]=option[1]; - } - if(!options->host) - options->host="127.0.0.1"; - if(!options->user) - options->user="root"; - if(!options->port) - options->port=1900; - else - options->port=(int)options->port; - - options->file = argv[-1]; - - string server_path = "/usr/local/lib/steam"; - - master()->add_include_path(server_path+"/server/include"); - master()->add_program_path(server_path+"/server/"); - master()->add_program_path(server_path+"/server/modules/groups.pike"); - master()->add_program_path(server_path+"/conf/"); - master()->add_program_path(server_path+"/spm/"); - master()->add_program_path(server_path+"/server/net/coal/"); - - conn = ((program)"client_base.pike")(); -// groups_pgm = ((program)"groups.pike")(); - int start_time = time(); - - werror("Connecting to sTeam server...\n"); - while ( !conn->connect_server(options->host, options->port) ) - { - if ( time() - start_time > 120 ) - { - throw (({" Couldn't connect to server. Please check steam.log for details! \n", backtrace()})); - } - werror("Failed to connect... still trying ... (server running ?)\n"); - sleep(10); - } - - if(lower_case(options->user) == "guest") - { - ping(options->host, options->port, options->user); - return options; - } - - mixed err; - string pw; - int tries=3; - //readln->set_echo( 0 ); - do - { - pw = Input.read_password( sprintf("Password for %s@%s", options->user, - options->host), "steam" ); -// pw ="steam"; - //pw=readln->read(sprintf("passwd for %s@%s: ", options->user, options->host)); - } - while((err = catch(conn->login(options->user, pw, 1))) && --tries); - //readln->set_echo( 1 ); - - if ( err != 0 ) - { - werror("Failed to log in!\nWrong Password!\n"); - exit(1); - } - ping(options->host, options->port, options->user, pw); - return options; -} - diff --git a/tools/steam-shell.pike b/tools/steam-shell.pike index 7470e7a..91970e7 100755 --- a/tools/steam-shell.pike +++ b/tools/steam-shell.pike @@ -20,38 +20,48 @@ * $Id: debug.pike.in,v 1.1 2008/03/31 13:39:57 exodusd Exp $ */ -constant cvs_version="$Id: debug.pike.in,v 1.1 2008/03/31 13:39:57 exodusd Exp $"; +constant cvs_version = "$Id: debug.pike.in,v 1.1 2008/03/31 13:39:57 exodusd Exp $"; inherit "applauncher.pike"; +inherit "client.pike"; #define OBJ(o) _Server->get_module("filepath:tree")->path_to_object(o) +#include Stdio.Readline readln; mapping options; -int flag=1,c=1; -string pw,str; +int flag = 1, c = 1; +string pw, str; + object me; -protected class StashHelp { - inherit Tools.Hilfe; - string help(string what) { return "Show STASH help"; } +protected + +class StashHelp { + inherit Tools.Hilfe; - void exec(Evaluator e, string line, array(string) words, - array(string) tokens) { - line = words[1..]*" "; - function(array(string)|string, mixed ... : void) write = e->safe_write; + string help(string what) { + return "Show STASH help"; + } - constant all = #" + void exec(Evaluator e, string line, array(string) words, + array(string) tokens) { + line = words[1..]*" "; + function(array(string) | string, mixed ... : void) write = e->safe_write; + + constant all =#" list List Gates/Exits, Documents, Containers in the current Room. goto Goto a Room using a full path to the Room. title Set your own description. room Describe the Room you are currently in. look Look around the Room. take Copy a object in your inventory. -gothrough Go through a gate. -create Create an object (File/Container/Exit) in current Room. +enter Enter a Room, Gate or Exit. +create Create an object (File/Container/Exit). Provide the full path of the destination or a . if you want it in current folder. peek Peek through a container. inventory(i) List your inventory. edit Edit a file in the current Room. +join Join a group. +leave Leave a group. hilfe Help for Hilfe commands. "; switch(line) { @@ -78,11 +88,11 @@ hilfe Help for Hilfe commands. case "take": write("Copy a object in your inventory.\n"); return; - case "gothrough": - write("Go through a gate.\n"); + case "enter": + write("Enter a Room, Gate or Exit.\n"); return; case "create": - write("Create an object (File/Container/Exit) in current Room.\n"); + write("Create an object (File/Container/Exit). Provide the full path of the destination or a . if you want it in current folder.\n"); return; case "peek": write("Peek through a container.\n"); @@ -94,6 +104,12 @@ hilfe Help for Hilfe commands. case "edit": write("Edit a file in the current Room.\n"); return; + case "join": + write("Join a group.\n"); + return; + case "leave": + write("Leave a group.\n"); + return; //Hilfe internal help case "me more": write( documentation_help_me_more ); @@ -114,55 +130,58 @@ Rewritten by Martin Nilsson 2002 write(all); write("\n\nEnter \"help me more\" for further Hilfe help.\n\n"); } - } } -class Handler -{ - inherit Tools.Hilfe.Evaluator; - inherit Tools.Hilfe; +class Handler { + + inherit Tools.Hilfe.Evaluator; + inherit Tools.Hilfe; + + object p; + void create(mapping _constants) { + + readln = Stdio.Readline(); + p = ((program) "tab_completion.pmod")(); + readln = p->readln; + write = predef::write; + ::create(); + p->load_hilferc(); + p->constants += _constants; //For listing sTeam commands and objects on tab + constants = p->constants; //For running those commands + readln->get_input_controller()->bind("\t", p->handle_completions); + commands->help = StashHelp(); + commands->hilfe = CommandHelp(); + } - object p; - void create(mapping _constants) - { - readln = Stdio.Readline(); - p = ((program)"tab_completion.pmod")(); - readln = p->readln; - write=predef::write; - ::create(); - p->load_hilferc(); - p->constants+=_constants; //For listing sTeam commands and objects on tab - constants = p->constants; //For running those commands - readln->get_input_controller()->bind("\t",p->handle_completions); - commands->help = StashHelp(); - commands->hilfe = CommandHelp(); - } + void add_constants(mapping a) { - void add_constants(mapping a) - { - constants = constants + a; - } -/* void add_variables(mapping a) - { - variables = variables + a; - }*/ + constants = constants + a; + } + /* void add_variables(mapping a) + { + variables = variables + a; + }*/ } -object _Server,users; +object _Server, users; mapping all; -string path="/"; +string path = "/"; Stdio.Readline.History readline_history; + void ping() { call_out(ping, 10); mixed a = conn->send_command(14, 0); + + if(a=="sTeam connection lost.") { flag = 0; readln->set_prompt(getpath()+"~ "); - conn = ((program)"client_base.pike")(); - conn->close(); + // conn = ((program)"client_base.pike")(); + conn = ((program)compile_file("../server/client_base.pike"))(); + conn->close(); if(conn->connect_server(options->host, options->port)) { remove_call_out(ping); @@ -182,9 +201,13 @@ void ping() object handler, conn; mapping myarray; +array(string) command_arr; + int main(int argc, array(string) argv) { - options=init(argv); + options = ([ "file":"/etc/shadow" ]); + options = options + init(argv); + options->historyfile=getenv("HOME")+"/.steam_history"; _Server=conn->SteamObj(0); users=_Server->get_module("users"); me = users->lookup(options->user); @@ -210,17 +233,18 @@ int main(int argc, array(string) argv) "room" : desc_room, "look" : look, "take" : take, - "gothrough" : gothrough, + "enter" : enter, "create" : create_ob, "peek" : peek, "inventory" : inventory, "i" : inventory, "edit" : editfile, + "join" : join, + "leave" : leave, ]); // Regexp.SimpleRegexp a = Regexp.SimpleRegexp("[a-zA-Z]* [\"|'][a-zA-Z _-]*[\"|']"); array(string) command_arr; - while((command=readln->read( - sprintf("%s", (handler->state->finishedp()?getstring(1):getstring(2)))))) + while((command=readln->read(sprintf("%s", (handler->state->finishedp()?getstring(1):getstring(2)))))) { if(sizeof(command)) { @@ -240,40 +264,83 @@ int main(int argc, array(string) argv) myarray[command_arr[0]](command_arr[1],command_arr[2]); else if(num==1) myarray[command_arr[0]](); + else if(num==4) + myarray[command_arr[0]](command_arr[1],command_arr[2],command_arr[3]); + else + myarray[command_arr[0]](@command_arr[1..]); }; if(result!=0) { + write(result[0]); write("Wrong command.||maybe some bug.\n"); } - } - else - handler->add_input_line(command); -// array hist = handler->history->status()/"\n"; -// if(hist) -// if(search(hist[sizeof(hist)-3],"sTeam connection lost.")!=-1){ -// handler->write("came in here\n"); -// flag=0; -// } - handler->p->set(handler->variables); - continue; + // else { continue; } } -// else { continue; } - } - handler->add_input_line("exit"); + handler->add_input_line("exit"); } -mapping init(array argv) -{ - mapping options = ([ "file":"/etc/shadow" ]); +void exec_command(string command) { + myarray = ([ + "list" : list, + "goto" : goto_room, + "title" : set_title, + "room" : desc_room, + "look" : look, + "take" : take, + "gothrough" : gothrough, + "create" : create_ob, + "peek" : peek, + "inventory" : inventory, + "i" : inventory, + "edit" : editfile, + ]); + + command_arr = command / " "; + + if (myarray[command_arr[0]]) { + int num = sizeof (command_arr); + mixed result = catch { + if (num == 2) + myarray[command_arr[0]](command_arr[1]); + else if (num == 3) + myarray[command_arr[0]](command_arr[1], command_arr[2]); + else if (num == 1) + myarray[command_arr[0]](); + else if (num == 4) + myarray[command_arr[0]](command_arr[1], command_arr[2], command_arr[3]); + else + myarray[command_arr[0]](@command_arr[1..]); + }; + + if (result != 0) { + write(result[0]); + write("Wrong command.||maybe some bug.\n"); + } + } + + else - array opt=Getopt.find_all_options(argv,aggregate( - ({"file",Getopt.HAS_ARG,({"-f","--file"})}), - ({"host",Getopt.HAS_ARG,({"-h","--host"})}), - ({"user",Getopt.HAS_ARG,({"-u","--user"})}), - ({"port",Getopt.HAS_ARG,({"-p","--port"})}), + handler->add_input_line(command); + + +} +mapping init(array argv) { + + mapping options = ([ "file" : "/etc/shadow" ]); + + array opt = Getopt.find_all_options(argv, aggregate( + ({"file", Getopt.HAS_ARG, ( + {"-f", "--file"})}), + ({"host", Getopt.HAS_ARG, ( + {"-h", "--host"})}), + ({"user", Getopt.HAS_ARG, ( + {"-u", "--user"})}), + ({"port", Getopt.HAS_ARG, ( + {"-p", "--port"})}), )); + options->historyfile=getenv("HOME")+"/.steam_history"; foreach(opt, array option) @@ -285,7 +352,7 @@ mapping init(array argv) if(!options->user) options->user="root"; if(!options->port) - options->port=1900; + options->port=1999; else options->port=(int)options->port; @@ -297,8 +364,8 @@ mapping init(array argv) master()->add_program_path(server_path+"/spm/"); master()->add_program_path(server_path+"/server/net/coal/"); - conn = ((program)"client_base.pike")(); - + conn = ((program)"../server/client_base.pike")(); +// conn = ((program)compile_file("../server/client_base.pike"))(); int start_time = time(); werror("Connecting to sTeam server...\n"); @@ -311,29 +378,26 @@ mapping init(array argv) werror("Failed to connect... still trying ... (server running ?)\n"); sleep(10); } - ping(); - if(lower_case(options->user) == "guest") - return options; - - mixed err; - int tries=3; - //readln->set_echo( 0 ); - do - { - pw = Input.read_password( sprintf("Password for %s@%s", options->user, - options->host), "steam" ); - //pw=readln->read(sprintf("passwd for %s@%s: ", options->user, options->host)); - } - while((err = catch(conn->login(options->user, pw, 1))) && --tries); - //readln->set_echo( 1 ); - if ( err != 0 ) - { - werror("Failed to log in!\nWrong Password!\n"); - exit(1); - } - return options; + if(lower_case(options->user) == "guest") + return options; + + mixed err; + int tries = 3; + //readln->set_echo( 0 ); + do { + pw = Input.read_password(sprintf("Password for %s@%s", options->user, + options->host), "steam"); + //pw=readln->read(sprintf("passwd for %s@%s: ", options->user, options->host)); + } while ((err = catch (conn->login(options->user, pw, 1))) && --tries); + //readln->set_echo( 1 ); + + if (err != 0) { + + werror("Failed to log in!\nWrong Password!\n"); + exit(1); + } } mapping assign(object conn, object _Server, object users) @@ -355,7 +419,9 @@ mapping assign(object conn, object _Server, object users) "room" : desc_room, "look" : look, "take" : take, - "gothrough" : gothrough, + "enter" : enter, + "join" : join, + "leave" : leave, // from database.h : "_SECURITY" : _Server->get_module("security"), @@ -387,69 +453,118 @@ mapping assign(object conn, object _Server, object users) ]); } -// create new sTeam objects -// with code taken from the web script create.pike -mixed create_object(string|void objectclass, string|void name, void|string desc, void|mapping data) +void leave(string what,void|string name) { - if(!objectclass && !name) + if(what=="group") { - write("Usage: create(string objectclass, string name, void|string desc, void|mapping data\n"); - return 0; + if(!stringp(name)){ + write("leave group \n"); + return; + } + object group = _Server->get_module("groups")->get_group(name); + if(group == 0){ + write("The group does not exists\n"); + return; + } + if(group->remove_member(me)) + { + write("Left group "+name+"\n"); + } + else + { + write("You are not a member of the group "+name+"\n"); + } } - object _Server=conn->SteamObj(0); - object created; - object factory; - - if ( !stringp(objectclass)) - return "No object type submitted"; - - factory = _Server->get_factory(objectclass); +} - switch(objectclass) +void join(string what,void|string name) +{ + if(what=="group") { - case "Exit": - if(!data->exit_from) - return "exit_from missing"; - break; - case "Link": - if(!data->link_to) - return "link_to missing"; - break; + if(!stringp(name)){ + write("join group \n"); + return; + } + object group = _Server->get_module("groups")->get_group(name); + if(group == 0){ + write("The group does not exists\n"); + return; + } + int result = group->add_member(me); + switch(result){ + case 1:write("Joined group "+name+"\n"); + break; + case 0:write("Couldn't join group "+name+"\n"); + break; + case -1:write("pending\n"); + break; + case -2:write("pending failed"); + break; + } } +} - if(!data) - data=([]); - created = factory->execute(([ "name":name ])+ data ); - - if(stringp(desc)) - created->set_attribute("OBJ_DESC", desc); - -// if ( kind=="gallery" ) -// { -// created->set_acquire_attribute("xsl:content", 0); -// created->set_attribute("xsl:content", -// ([ _STEAMUSER:_FILEPATH->path_to_object("/stylesheets/gallery.xsl") ]) -// ); -// } - -// created->move(this_user()); +// create new sTeam objects +// with code taken from the web script create.pike +mixed create_object(string | void objectclass, string | void name, void | string desc, void | mapping data) { + if (!objectclass && !name) { + write("Usage: create(string objectclass, string name, void|string desc, void|mapping data\n"); + return 0; + } + object _Server = conn->SteamObj(0); + object created; + object factory; + + if (!stringp(objectclass)) + return "No object type submitted"; + + factory = _Server->get_factory(objectclass); + + switch (objectclass) { + case "Exit": + if (!data->exit_from) + return "exit_from missing"; + break; + case "Link": + if (!data->link_to) + return "link_to missing"; + break; + } + + if (!data) + data = ([]); + created = factory->execute(([ "name" : name ]) + data); + + if (stringp(desc)) + created->set_attribute("OBJ_DESC", desc); + + // if ( kind=="gallery" ) + // { + // created->set_acquire_attribute("xsl:content", 0); + // created->set_attribute("xsl:content", + // ([ _STEAMUSER:_FILEPATH->path_to_object("/stylesheets/gallery.xsl") ]) + // ); + // } + + // created->move(this_user()); + + return created; + } - return created; -} +string getstring(int i) { + // write("came in here\n"); + string curpath = getpath(); + if (i == 1 && flag == 1) + return curpath + "> "; + else if (i == 1 && (flag == 0)) + return curpath + "~ "; + else if (i == 2 && flag == 1) + return curpath + ">> "; + else if (i == 2 && (flag == 0)) + + return curpath + "~~ "; + } -string getstring(int i) -{ -// write("came in here\n"); - string curpath = getpath(); - if(i==1&&flag==1) - return curpath+"> "; - else if(i==1&&(flag==0)) - return curpath+"~ "; - else if(i==2&&flag==1) - return curpath+">> "; - else if(i==2&&(flag==0)) - return curpath+"~~ "; -} int list(string what) { @@ -465,72 +580,101 @@ int list(string what) if(sizeof(display)==0) toappend = "There are no "+what+" in this room\n"; else - toappend = "Here is a list of all "+what+" in the current room\n"; + toappend = "Here is a list of all "+what+"\n"; + foreach(display,string str) { - a=a+(str+" "); + a=a+(str+"\n"); if(str=="Invalid command") { flag=1; write(str+"\n"); } } - if(flag==0) - write(toappend+a+"\n\n"); - return 0; + if(flag==0){ + mapping mp = Process.run("tput cols"); + int screenwidth = (int)mp["stdout"]; + write(toappend + "\n"); + write("%-$*s\n", screenwidth,a); + write("\n"); + } + return !flag;//flag = 1 when str = Invalid command that means execution failed } array(string) get_list(string what,string|object|void lpath) { -// string name; -// object to; - array(string) gates=({}),containers=({}),documents=({}),rooms = ({}),rest=({}); -// mapping(string:object) s = ([ ]); + array(string) whatlist = ({}); object pathobj; - if(!lpath) - pathobj = OBJ(getpath()); - else if(stringp(lpath)) - pathobj = OBJ(lpath); - else if(objectp(lpath)) - pathobj = lpath; -// string pathfact = _Server->get_factory(pathobj)->query_attribute("OBJ_NAME"); - mixed all = pathobj->get_inventory_by_class(0x3cffffff); //CLASS_ALL - foreach(all, object obj) + if(!lpath) + pathobj = OBJ(getpath()); + else if(stringp(lpath)) + pathobj = OBJ(lpath); + else if(objectp(lpath)) + pathobj = lpath; + switch (what) { - string fact_name = _Server->get_factory(obj)->query_attribute("OBJ_NAME"); - string obj_name = obj->query_attribute("OBJ_NAME"); -// write("normally : "+obj_name+"\n"); - if(fact_name=="Document.factory") - documents = Array.push(documents,obj_name); -// write(obj_name+"\n"); - else if(fact_name=="Exit.factory"){ - string fullgate = obj_name+" : "+obj->get_exit()->query_attribute("OBJ_NAME"); - gates = Array.push(gates,fullgate); -// write("in gates : "+fullgate+"\n"); + case "containers": + { + mixed all = pathobj->get_inventory_by_class(CLASS_CONTAINER); + foreach(all, object obj) + { + string obj_name = obj->query_attribute("OBJ_NAME"); + whatlist = Array.push(whatlist,obj_name); + } } - else if(fact_name=="Container.factory") - containers = Array.push(containers,obj_name); -// write("in containers : "+obj_name+"\n"); - else if(fact_name=="Room.factory") - rooms = Array.push(rooms,obj_name); - else - rest = Array.push(rest, obj_name); + break; + case "files": + { + mixed all = pathobj->get_inventory_by_class(CLASS_DOCUMENT|CLASS_DOCLPC|CLASS_DOCEXTERN|CLASS_DOCHTML|CLASS_DOCXML|CLASS_DOCXSL); + foreach(all, object obj) + { + string obj_name = obj->query_attribute("OBJ_NAME"); + whatlist = Array.push(whatlist,obj_name); + } + } + break; + case "exits": + case "gates": + case "rooms": + { + mixed all = pathobj->get_inventory_by_class(CLASS_ROOM|CLASS_EXIT); + foreach(all, object obj) + { + string obj_name = obj->query_attribute("OBJ_NAME"); + whatlist = Array.push(whatlist,obj_name); + } + } + break; + case "groups": + { + array(object) groups = _Server->get_module("groups")->get_groups(); + foreach(groups,object group) + { + string obj_name = group->get_name(); + whatlist = Array.push(whatlist,obj_name); + } + } + break; + case "others": + { + mixed all = pathobj->get_inventory_by_class(CLASS_ALL); + foreach(all, object obj) + { + string fact_name = _Server->get_factory(obj)->query_attribute("OBJ_NAME"); + if(!(fact_name == "Group.factory" || fact_name == "Room.factory" || fact_name == "Exit.factory" || fact_name == "Container.factory" || fact_name == "Document.factory" || fact_name == "DocExtern.factory")) + { + string obj_name = obj->query_attribute("OBJ_NAME"); + whatlist = Array.push(whatlist,obj_name); + } + } + } + break; + default: + whatlist = ({"Invalid command"}); } - if(what=="gates") - return gates; - else if(what=="rooms") - return rooms; - else if(what=="containers") - return containers; - else if(what=="files") - return documents; - else if(what=="others") - return rest; - else - return ({"Invalid command"}); + return whatlist; } - int goto_room(string where) { string roomname=""; @@ -548,50 +692,45 @@ int goto_room(string where) pathobj = OBJ(where); if(!pathobj) //Relative room checking { - if(getpath()[-1]==47) //check last "/" - { - pathobj = OBJ(getpath()+where); - where=getpath()+where; - } - else - { - pathobj = OBJ(getpath()+"/"+where); - where=getpath()+"/"+where; - } + pathobj = OBJ(getpath()+"/"+where); + where=getpath()+"/"+where; } roomname = pathobj->query_attribute("OBJ_NAME"); - string factory = _Server->get_factory(pathobj)->query_attribute("OBJ_NAME"); - //DONT NEED THIS. NEED TO USE me->move() to these locations -// if(pathobj&&((factory=="Room.factory")||(factory=="User.factory")||(factory=="Container.factory"))) -// path = where; - string oldpath = getpath(); - mixed error = catch{ + string factory = _Server->get_factory(pathobj)->query_attribute("OBJ_NAME"); + //DONT NEED THIS. NEED TO USE me->move() to these locations + // if(pathobj&&((factory=="Room.factory")||(factory=="User.factory")||(factory=="Container.factory"))) + // path = where; + string oldpath = getpath(); + mixed error = catch { me->move(pathobj); - write("You are now inside "+roomname+"\n"); + write("You are now inside " + roomname + "\n"); }; - if(error && pathobj) { write("Please specify path to room. Not a "+((factory/".")[0])+"\n"); me->move(OBJ(oldpath)); + return 0; } else if(error) { write("Please specify correct path to a room.\n"); + return 0; } // } // roomname = pathobj->query_attribute("OBJ_NAME"); // write("You are now inside "+roomname+"\n"); - return 0; + return 1; } int set_title(string desc) { if(users->lookup(options->user)->set_attribute("OBJ_DESC",desc)) write("You are now described as - "+desc+"\n"); - else + else{ write("Cannot set description.\n"); - return 0; + return 0; + } + return 1; } int desc_room() @@ -603,7 +742,7 @@ int desc_room() if((desc=="")||(Regexp.match("^ +$",desc))) desc = "This room does not have a description yet.\n"; write("You are currently in "+pathobj->query_attribute("OBJ_NAME")+"\n"+desc+"\n"); - return 0; + return 1; } int look(string|void str) @@ -618,20 +757,15 @@ int look(string|void str) write("---------------\n"); list("containers"); write("---------------\n"); - list("gates"); - write("---------------\n"); list("rooms"); write("---------------\n"); - return 0; + return 1; } int take(string name) { string fullpath=""; - if(getpath()[-1]==47) //check last "/" - fullpath = getpath()+name; - else - fullpath = getpath()+"/"+name; + fullpath = getpath()+"/"+name; object orig_file = OBJ(fullpath); if(orig_file) { @@ -639,23 +773,26 @@ int take(string name) dup_file->move(me); write(name+" copied to your rucksack.\n"); } - else + else{ write("Please mention a file in this room."); - return 0; + return 0; + } + return 1; } -int gothrough(string gatename) +int enter(string gatename) { string fullpath = ""; - if(getpath()[-1]==47) //check last "/" - fullpath = getpath()+gatename; - else - fullpath = getpath()+"/"+gatename; + fullpath = getpath()+"/"+gatename; object gate = OBJ(fullpath); if(gate) { - object exit = gate->get_exit(); - string exit_path1 = "",exit_path2 = ""; + string exit_path1 = fullpath,exit_path2 = ""; + if(_Server->get_factory(gate)->query_attribute("OBJ_NAME")=="Exit.factory") + { + object exit = gate->get_exit(); + exit_path1 = exit->query_attribute("OBJ_PATH"); //change to object_to_path + } // exit_path1 = _Server->get_module("filepath:tree")->check_tilde(exit); // exit_path2 = _Server->get_module("filepath:tree")->object_to_path(exit); // if(exit_path1!="") @@ -664,57 +801,71 @@ int gothrough(string gatename) // goto_room(exit_path2); // else // write("Problem with object_to_path\n"); - exit_path1 = exit->query_attribute("OBJ_PATH"); //change to object_to_path + if(exit_path1!="") goto_room(exit_path1); } else + { write(gatename+" is not reachable from current room\n"); - return 0; + return 0; + } + return 1; } int delete(string file_cont_name) { string fullpath=""; - if(getpath()[-1]==47) //check last "/" - fullpath = getpath()+file_cont_name; - else - fullpath = getpath()+"/"+file_cont_name; + fullpath = getpath()+"/"+file_cont_name; if(OBJ(fullpath)) return 0; return 0; } -int create_ob(string type,string name) +int create_ob(string type,string name,string destination) { string desc = readln->read("How would you describe it?\n"); mapping data = ([]); type = String.capitalize(type); + if(destination == ".") + destination = getpath(); if(type=="Exit") { object exit_to = OBJ(readln->read("Where do you want to exit to?(full path)\n")); - object exit_from = OBJ(getpath()); - data = ([ "exit_from":exit_from, "exit_to":exit_to ]); +// object exit_from = OBJ(getpath()); + data = ([ "exit_from":OBJ(destination), "exit_to":exit_to ]); } else if(type=="Link") { object link_to = OBJ(readln->read("Where does the link lead?\n")); data = ([ "link_to":link_to ]); } + else if(type=="Group") + { + string parent = readln->read("Subgroup of?\n"); + data = (["parentgroup":parent]); + } object myobj = create_object(type,name,desc,data); - if(type=="Room") - myobj->move(OBJ(getpath())); - - return 0; +/* if(type=="Room" || type=="Container"){ + if(destination==".") + myobj->move(OBJ(getpath())); + else + myobj->move(OBJ(destination)); + } + */ + if(!(type == "Exit" || type=="Group")) + myobj->move(OBJ(destination)); + if(type=="Group") + { + myobj->add_member(me); + } + return 1; } int peek(string container) { string fullpath = ""; - if(getpath()[-1]==47) //check last "/" - fullpath = getpath()+container; - else - fullpath = getpath()+"/"+container; + fullpath = getpath()+"/"+container; string pathfact = _Server->get_factory(OBJ(fullpath))->query_attribute("OBJ_NAME"); if(pathfact=="Room.factory") { @@ -731,21 +882,22 @@ int peek(string container) write("You peek into "+container+"\n\n"); display("containers", conts); display("files", files); + return 1; } -void display(string type, array(string) strs) -{ - if(sizeof(strs)==0) - write("There are no "+type+" here\n"); - else if(sizeof(strs)==1) - write("There is 1 "+type[0..sizeof(type)-2]+" here\n"); - else - write("There are "+sizeof(strs)+" "+type+" here\n"); - foreach(strs, string str) - { - write(str+" "); - } - write("\n-----------------------\n"); +void display(string type, array(string) strs) { + if (sizeof (strs) == 0) + write("There are no " + type + " here\n"); + else if (sizeof (strs) == 1) + write("There is 1 " + type[0..sizeof (type) - 2] + " here\n"); + + else + write("There are " + sizeof (strs) + " " + type + " here\n"); + foreach(strs, string str) { + + write(str + " "); + } + write("\n-----------------------\n"); } int inventory() @@ -757,29 +909,41 @@ int inventory() display("containers", conts); display("files", files); display("other files", others); + return 1; } -int editfile(string filename) +int editfile(string...args) { - string fullpath = ""; - if(getpath()[-1]==47) //check last "/" - fullpath = getpath()+filename; - else - fullpath = getpath()+"/"+filename; - string pathfact = _Server->get_factory(OBJ(fullpath))->query_attribute("OBJ_NAME"); - if(pathfact=="Document.factory") - applaunch(OBJ(fullpath),exitnow); - else - write("You can't edit a "+pathfact[0..sizeof(pathfact)-8]); - return 0; + int size = sizeof(args); + if(size<1){ + write("Please provide a file name\n"); + return 0; + } + array(string) fullpatharr = allocate(size); + array(string) pathfactarr = allocate(size); + array(object) obj = allocate(size); + for(int j = 0;jget_factory(OBJ(fullpatharr[j]))->query_attribute("OBJ_NAME"); + + if(pathfactarr[j]!="Document.factory"){ + write("You can't edit a "+pathfactarr[j][0..sizeof(pathfactarr[j])-8]); + return 0; + } + obj[j] = OBJ(fullpatharr[j]); + } + + applaunch(obj,exitnow); + + return 1; } -void exitnow() -{} +void exitnow() { +} -string getpath() -{ - return me->get_last_trail()->query_attribute("OBJ_PATH"); +string getpath() { + return me->get_last_trail()->query_attribute("OBJ_PATH"); } -constant stash_help_doc = #"This is a sTeam Advanced Shell. All the STASH commands work with normal pike commands. Tab completion is available for both STASH commands and pike commands.\n\n"; +constant stash_help_doc =#"This is a sTeam Advanced Shell. All the STASH commands work with normal pike commands. Tab completion is available for both STASH commands and pike commands.\n\n"; + diff --git a/tools/steam-shell.vim b/tools/steam-shell.vim new file mode 100644 index 0000000..19d8fd2 --- /dev/null +++ b/tools/steam-shell.vim @@ -0,0 +1,62 @@ +command! Steam call Steamshell() +command! -nargs=1 Open call Open() +command! Upload call Upload() +autocmd BufWritePost * Upload + +"Note: This file needs to be included in the applauncher.pike in the function call edit(array(object)) +"Function Usage +"Enter the Vi insert mode (i) and type the commands +"Enter the Vi visual mode(v). Select the command using the Vi Visual mode. +"Now type : y To yank the text +"Now enter the command Steam +"It would prompt you to enter steam password. After this the output of the command shall be displayed in a the log buffer which would be opened in a new tab. + +function! Steamshell() +"tab sb 2 displays the contents of the buffer 2 in a new tab. +"In this case the buffer 2 stands for the log buffer. +"In future if a vim script is included the buffer number should be noted down for the log buffer using :ls and the below command should be modified to include the changes in it. +"The contents selected in the Vi visual mode are savied in the "* register. The contents of this register are appended as an argument to the command which is simulated using execute command. +"r! Execute {cmd} and insert its standard output below the cursor or the specified line. + let @0 = substitute(@0, '\n', " ", "g") + execute "tab sb 1 | r! /usr/local/lib/steam/tools/steam-shell.pike". " '".@0."'" + silent !clear +endfunction + +function! Open(name) + + "pike code to fetch and store the contents of the file in a temporary file + + let code = 'inherit "/usr/local/lib/steam/tools/applauncher.pike";string open(){string fullpath="'.a:name.'";string pathfact=_Server->get_factory(OBJ(fullpath))->query_attribute("OBJ_NAME");if (pathfact \!= "Document.factory") {write("you can not edit this file.");return 0;}object obj = OBJ(fullpath);object xslobj;if(obj->get_identifier()[sizeof(obj->get_identifier())-8..]==".xsl.xml"){string xslnamex=obj->get_identifier()[..sizeof(obj->get_identifier())-9]+ ".xsl";xslobj=obj->get_environment()->get_object_byname(xslnamex);}string content = obj->get_content();string dir;dir="/tmp/"+(MIME.encode_base64(Crypto.Random.random_string(10), 1)-("/"))+System.getpid();mkdir(dir,0700);string filename=obj->get_object_id()+"-"+obj->get_identifier();filename=dir+"/"+filename;string debugfilename=filename+"-disp";Stdio.write_file(filename,content||"",0600);Stdio.write_file(debugfilename,"This is your log window\n",0600);send_message(sprintf("(opened \%O \%s)\n", obj,filename),debugfilename);vim_upload(({filename}),({obj}),({xslobj}));return filename;}open();' + + "store the result of execution of pike script + execute "tabnew |r! /usr/local/lib/steam/tools/steam-shell.pike"." '".code."'" + silent !clear + "extract the file name from the result + "copy the results of pike script to the variable result + let @a='' + %ya + let result = @a + "search for Result: and copy that line to register A + let @a='' + g/Result:/y A + let result = @a + "split the line based on space, the name of the file is the second element + let x = split(result,"\"") + "close the file containing the result of the pike script + q! + execute("tabnew ".x[1]."-disp"."|sp ".x[1]) + + let g:path=a:name +endfunction + +function! Upload() + "upload needs to be implemented + write + if exists("g:path") + let code = 'inherit "/usr/local/lib/steam/tools/applauncher.pike";string filename="'.@%.'";object obj=OBJ("'.g:path.'");object xslobj;if(obj->get_identifier()[sizeof(obj->get_identifier())-8..]==".xsl.xml"){string xslnamex=obj->get_identifier()[..sizeof(obj->get_identifier())-9]+ ".xsl";xslobj=obj->get_environment()->get_object_byname(xslnamex);}vim_upload(({filename}),({obj}),({xslobj}));' + execute "! /usr/local/lib/steam/tools/steam-shell.pike"." '".code."'" + silent !clear + endif +endfunction + +