diff --git a/src/server/simpleslave.c b/src/server/simpleslave.c
new file mode 100644
--- /dev/null
+++ b/src/server/simpleslave.c
@@ -0,0 +1,190 @@
+/*
+ Copyright 2009 Nathan Phillip Brink, Ethan Zonca, Matthew Orlando
+
+ This file is a part of DistRen.
+
+ DistRen is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ DistRen 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with DistRen. If not, see .
+
+*/
+
+#include "slavefuncs.h"
+
+#include "common/asprintf.h"
+#include "common/options.h"
+
+#include
+#include
+#include
+#include
+#include
+
+
+int main(int argc, char *argv[])
+{
+
+ char *datadir;
+ char *server;
+ char *username;
+ char *password; // @TODO: Binki: fill me with confiness
+ char *hostname;
+ cfg_opt_t myopts[] = {
+ CFG_SIMPLE_STR("username", &username),
+ CFG_SIMPLE_STR("datadir", &datadir),
+ CFG_SIMPLE_STR("server", &server),
+ CFG_SIMPLE_STR("hostname", &hostname),
+ CFG_END()
+ };
+ cfg_t * my_cfg;
+
+ struct options_common *commonopts;
+
+ // struct distrenjob *myjob; /* Structure to hold data gathered from the XML file */
+
+ // struct remoteio *comm_slave;
+
+ /**
+ initializations
+ */
+ datadir = NULL;
+ server = NULL;
+ username = NULL;
+
+ char curopt;
+
+ while(((char)-1) != (curopt = getopt(argc, argv, "u:th")))
+ {
+ if(curopt == ':')
+ {
+ fprintf(stderr, "-%c: is missing an argument\n", optopt);
+ return 1;
+ }
+ else if(curopt == '?')
+ {
+ fprintf(stderr, "-%c: invalid option specified\n", optopt);
+ return 1;
+ }
+ else if(curopt == 'h')
+ {
+ fprintf(stderr, "Usage: distrenslave [option] \nStarts a distren slave\n\t-u\tset username (run after fresh install)\n\t-t\tEnter test mode\n\t-h\tshow this help\n");
+ return 2;
+ }
+ else if(curopt == 't')
+ {
+ slaveTest();
+ return 0;
+ }
+ else if(curopt == 'u')
+ username = strdup(optarg);
+ fprintf(stderr, "Putting username \"%s\" in distrenslave.conf\n", username);
+ conf_replace("distrenslave.conf", "!username", username);
+ fprintf(stderr, "Please invoke distrenslave with no arguments to run with the username you just set\n");
+ return 0;
+ }
+
+ /* Get conf data */
+ options_init(argc, argv, &my_cfg, myopts, "slave", &commonopts);
+
+
+ /* Notifies the user if there no username in .conf */
+ if(checkUsername(username))
+ return 1;
+
+ /*
+ fprintf(stderr, "Connecting to server...\n");
+ if(remoteio_open(&comm_slave, commonopts->remoteio, server))
+ {
+ fprintf(stderr, "Error connecting to server; exiting\n");
+ return 1;
+ }
+*/
+
+ // Variables needed for main loop
+ int jobnum = 0;
+ int framenum = 0;
+ int slavekey = atoi(username); // @TODO: Make this more friendly
+
+ char *urltoTar; /* Full URL to the server-side location of job#.tgz */
+ char *pathtoTar; /* Full path to the location of the job#.tgz */
+
+ char *urltoOutput; /* Full URL where output is posted */
+ char *pathtoOutput; /* Full path to the output (rendered) file */
+
+ char *pathtoJobfile; /* Full path to the job's main file */
+ char *outputExt = "jpg"; /* Output Extension (e.g., JPG) */
+
+ int haveWork = 0;
+ int quit = 0;
+
+ // Main loop
+ while(!quit)
+ {
+
+ // request work
+ fprintf(stderr,"Requesting work...\n");
+ haveWork = _web_getwork(slavekey, password, &jobnum, &framenum);
+
+ /* If we got a frame */
+ if(haveWork)
+ {
+ fprintf(stderr,"Got work from server...\n");
+ /* @TODO: Add remotio hooks */
+ // jobnum = remoteio_read(jobnum); /* Set jobnum from remoteio (we could use info from struct, but we need this info to download the xmlfile */
+ // framenum = remoteio_read(jobnum); /* Set framenum from remoteio */
+ // outputExt = remotio)read(outputExt); /* Set output extension from remotio */
+
+ fprintf(stderr, "Preparing to render frame %d in job %d\n", framenum, jobnum);
+
+ prepareJobPaths(jobnum, framenum, outputExt, datadir, &urltoTar, &pathtoTar, &pathtoJobfile, &urltoOutput, &pathtoOutput);
+ free(outputExt);
+
+ if(downloadTar(urltoTar, pathtoTar))
+ return 1;
+
+ unpackJob(pathtoTar, jobnum);
+
+ /* Execute blender */
+ if(exec_blender(pathtoJobfile, pathtoOutput, framenum))
+ {
+ fprintf(stderr,"Error running Blender. Check your installation and/or your PATH.\n");
+ return 1;
+ }
+ free(pathtoJobfile);
+
+ /* Post-execution */
+ fprintf(stderr, "Finished frame %d in job %d, uploading...\n", framenum, jobnum);
+ uploadOutput(pathtoOutput, urltoOutput, jobnum, framenum, slavekey); // @TODO: Handle return value
+
+ free(urltoOutput);
+ free(pathtoOutput);
+
+ // Tell the server that rendering and upload are complete
+ _web_finishframe(slavekey, password, jobnum, framenum);
+ }
+ else
+ fprintf(stderr,"Nothing to do. Idling...\n");
+
+ // @TODO: If the server says that every frame for the last jobnum is finished, OR if the data is getting old
+ if(1 == 0)
+ {
+ // Note: individual frames are already deleted after uploading,
+ // except for ones that couldn't be uploaded
+ delete_jobdata(jobnum, datadir);
+ }
+
+ sleep(5); // Poll 5 seconds. @TODO: Remove all polling
+ }
+
+ fprintf(stderr,"Goodbye!\n");
+ return 0;
+}