Changeset - a47f25c479d3
[Not reviewed]
default
0 4 0
Nathan Brink (binki) - 15 years ago 2010-03-25 10:14:20
ohnobinki@ohnopublishing.net
fix warnings, fix initializations
4 files changed with 38 insertions and 24 deletions:
0 comments (0 inline, 0 general)
src/common/execio.c
Show inline comments
 
@@ -7,96 +7,96 @@
 
  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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "execio.h"
 

	
 
#include <unistd.h>
 
#include <sys/types.h>
 
#ifndef _WIN32
 
#include <sys/wait.h>
 
#endif
 
#include <signal.h>
 
#include <malloc.h>
 
#include <fcntl.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <errno.h>
 

	
 
int execio_open(struct execio **rem, const char *progname, char *const argv[])
 
{
 
  /* pipe used to write to child */
 
  int pipe_write[2];
 
  /* pipe used to read from child */
 
  int pipe_read[2];
 

	
 
  pid_t child;
 

	
 
  /* for wait(2) if needed */
 
  int childstatus;
 
  
 
  int counter;
 
  int counter2;
 
  int maxfds;
 

	
 
  /* create two pipes to facilitate communication with child */
 
  if(pipe(pipe_write))
 
    return 1;
 
  if(pipe(pipe_read))
 
    {
 
      close(pipe_write[0]);
 
      close(pipe_write[1]);
 
      return 1;
 
    }
 
  
 
  /* parent */
 
  child = fork();
 
  if(child == -1)
 
    {
 
      close(pipe_write[0]);
 
      close(pipe_write[1]);
 
      close(pipe_read[0]);
 
      close(pipe_read[1]);
 
      return 1;
 
    }
 
  if(child)
 
    /* the parent proc: */
 
    {
 
      /* close sides of pipe we won't use */
 
      close(pipe_write[0]);
 
      close(pipe_read[1]);
 
      
 
      /* setup execio struct */
 
      (*rem) = malloc(sizeof(struct execio));
 
      fprintf(stderr, "Allocated rem at %d\n", rem);
 
      if(!(*rem))
 
	{
 
	  /* we should tell the child we're dead - use wait and close our end of the pipes! */
 
	  close(pipe_write[1]);
 
	  close(pipe_read[0]);
 
	  /* we should probably pass of the wait() call to a thread that just does boring things like that. Especially for when the server tries to connect to other servers... */
 
	  /* maybe we should just kill instead of term the child */
 
	  kill(child, SIGTERM);
 
	  /* the waitpid(2) seems to indicate that only when the child is terminated will this wait return. */
 
	  waitpid(child, &childstatus, 0); 
 
	}
 
      (*rem)->pipe_write = pipe_write[1];
 
      (*rem)->pipe_read = pipe_read[0];
 
      (*rem)->state = 0;
 
      (*rem)->child = child;
 
      
 
      return 0;
 
    }
 
  
 
  /* child */
 
  else
 
    {
 
      /* close unused pipes */
 
      close(pipe_write[1]);
src/server/distrend.c
Show inline comments
 
@@ -88,48 +88,49 @@ int distrend_config_free(struct distrend
 
/* **************XML Functions**************** */
 
void update_general_info(struct general_info *geninfo);
 
int import_general_info(struct general_info *general_info);
 
int update_xml_joblist(struct general_info *geninfo);
 

	
 
/* **************Test Functions**************** */
 
int interactiveTest(int test, struct general_info *general_info);
 

	
 
/* **************** Main ********************* */
 
int main(int argc, char *argv[])
 
{
 
  /* Parse arguments */
 
  int counter;
 
  int test = 0; /*< Interactive mode if 1 */
 
  struct general_info general_info;
 
  struct distrend_clientset *clients;
 

	
 
  enum clientstatus
 
  {
 
    CLIENTSTATUS_UNINITIALIZED = 0,
 
    CLIENTSTATUS_BUSY = 1,
 
    CLIENTSTATUS_IDLE = 2
 
  } clientstatus;
 

	
 
  clientstatus = CLIENTSTATUS_UNINITIALIZED;
 
  // xmlinit();
 

	
 
  for(counter = 0; counter < argc; counter ++)
 
    {
 
      if(strcmp(argv[counter], "-h") == 0)
 
      {
 
    	  fprintf(stderr, "Usage: distrend [option] \nStarts the distrend server\n\t-h\tshow this help\n\t-t\tlaunches queue testing interface \n");
 
	  return 2;
 
      }
 

	
 
      else if(strcmp(argv[counter], "-t") == 0)
 
      {
 
    	  fprintf(stderr, "Entering into test mode...\n\n");
 
    	  test = 1;
 
      }
 
    }
 

	
 

	
 
  if(distrend_do_config(argc, argv, &general_info.config))
 
    return 1;
 

	
 
  /** preset paths */
 
  _distren_asprintf(&general_info.files.geninfo, "%s/general_info.xml",
 
		    general_info.config->datadir);
 
@@ -140,68 +141,73 @@ int main(int argc, char *argv[])
 
    {
 
      fprintf(stderr, "%s:%d: mysqlConnect() failed\n", __FILE__, __LINE__);
 
      fprintf(stderr, "don't test mysql stuff\n");
 
      interactiveTest(test, &general_info);
 
      return 1;
 
    }
 
  fprintf(stderr,"Finished connecting!\n");
 

	
 
  /** Execute test function */
 
  interactiveTest(test, &general_info);
 

	
 
  distrend_listen(general_info.config, &clients);
 

	
 
  int slaveKey = 0; // Remotio should set me on a per-slave basis
 
  /* Main Loop */
 
  while(!general_info.config->die)
 
    {
 
      int clientsays = 0; /*< temporary example variable, will be replaced when we can handle messages */
 

	
 
      distrend_accept(general_info.config, clients);
 

	
 
      /* Make the following code more event-driven */
 
      frame_watchdog(&general_info.head);
 

	
 
      struct frameset *frame;
 
      struct frameset frame;
 
      struct distrenjob *job;
 
      distrenjob_new(&job);
 

	
 
      memset(&frame, '\0', sizeof(frame));
 

	
 
      /* If the client is idle, must be modified for climbing through linked list of clients (client->clientnum) */
 
      if(clientstatus == CLIENTSTATUS_IDLE)
 
	{
 
	  int returnnum = find_jobframe(general_info.conn, slaveKey, &job->jobnum, &frame->num); // Finds a frame to render @FIXME: Slavenum :D
 
	  int returnnum = find_jobframe(general_info.conn, slaveKey, &job->jobnum, &frame.num); // Finds a frame to render @FIXME: Slavenum :D
 
	  if(returnnum)
 
	    {
 
	      fprintf(stderr,"No frames are available to render at this time. Idling...\n");
 
	      sleep(10);
 
	    }
 
	  else
 
	    remotio_send_to_client(frame->num, job->jobnum); // Pseudo-sends data to client
 
	    remotio_send_to_client(frame.num, job->jobnum); // Pseudo-sends data to client
 
	}
 
      /* If the client states that they finished the frame */
 
      	if(clientsays == DISTREN_REQUEST_DONEFRAME){
 
      	  clientstatus = CLIENTSTATUS_IDLE; // Sets the client back to idle
 
      	  finish_frame(general_info.conn, 0, job->jobnum, frame->num); // @TODO: Make sure this actually works.
 
      	}
 
      if(clientsays == DISTREN_REQUEST_DONEFRAME)
 
	{
 
	  clientstatus = CLIENTSTATUS_IDLE; // Sets the client back to idle
 
	  finish_frame(general_info.conn, 0, job->jobnum, frame.num); // @TODO: Make sure this actually works.
 
	}
 
      distrenjob_free(&job);
 
    }
 

	
 
  distrend_unlisten(general_info.config->listens, clients);
 
  distrend_config_free(general_info.config);
 

	
 
  xmlcleanup();
 

	
 
  /** free() paths */
 
  free(general_info.files.geninfo);
 
  mysqlDisconnect(general_info.conn);
 

	
 
  return 0;
 
}
 

	
 
/* ********************** Functions ************************* */
 

	
 
/**
 
   Performs command stored in a client's request. @TODO: Fill stub
 
*/
 
int distrend_do()
 
{
 
  return 0;
 
}
 

	
src/server/slavefuncs.c
Show inline comments
 
@@ -118,151 +118,158 @@ xmlNodePtr xml_quickxpath(xmlXPathContex
 

	
 
  xmlXPathFreeObject(xmlxpathobjptr);
 

	
 
  return toreturn;
 
}
 

	
 

	
 
/** Stub for deleting job data from the disk. @TODO: unstubify me! */
 
int delete_jobdata(int jobnum, char *datadir)
 
{
 
  char *jobpath;
 
  _distren_asprintf(&jobpath, "%s/%d", datadir, jobnum);
 
  // rmdir(jobpath);
 
  fprintf(stderr, "Please manually remove %s. Automatic removal is currently not implemented.\n", jobpath);
 
  return 0;
 
}
 

	
 
/** Function referenced by curlget() to write data to disk. */
 
size_t curl_writetodisk(void *ptr, size_t size, size_t nmemb, FILE *stream)
 
 {
 
    return fwrite(ptr, size, nmemb, stream);
 
  }
 

	
 
/** Helper function for cURL's progress display */
 
int curl_progress( char *Bar,double t,double d,double ultotal,double ulnow)
 
int curl_progress(char *Bar, double t, double d, double ultotal, double ulnow)
 
{
 
fprintf(stderr,"Downloading: %f%% complete\r",d/t*100);
 
return 0;
 
}
 

	
 
/** Retrieves a URL with cURL and saves it to disk */
 
int curlget(char *url, char *out){
 
CURLcode curlget(char *url, char *out){
 
  fprintf(stderr,"Preparing to download %s\n",url);
 
  double *Bar; // Stores cURL progress display info
 
  CURL *curl;
 
  CURLcode res;
 
  FILE *outfile;
 

	
 
  res = CURLE_FAILED_INIT;
 
  curl = curl_easy_init();
 
  if(curl) {
 
  if(curl)
 
    {
 
    outfile = fopen(out, "w"); // Open where we're writing to
 
    if(outfile == NULL)
 
      return 2; // Output dir doesn't exist
 
    curl_easy_setopt(curl, CURLOPT_URL, url);
 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_writetodisk); // this MUST be set for win32 compat.
 
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
 
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress);
 
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&curl_progress);
 
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &Bar);
 
    res = curl_easy_perform(curl);
 
    curl_easy_cleanup(curl);
 
    fclose(outfile);
 
  }
 
  fprintf(stderr,"\n"); // Clears out he progressbar's carriage return
 
  fclose(outfile);
 
  return res; // 0 is OK, 1 is 404 or other error
 
}
 

	
 
/** Posts a file to a url with cUrl */
 
int curlpost(char *filename, char *url, int jobnum, int framenum, int slavekey){
 
  fprintf(stderr,"Uploading to %s\n", url);
 
CURLcode curlpost(char *filename, char *url, int jobnum, int framenum, int slavekey)
 
{
 
  char *targetname = "uploadedfile"; // Name of the target in the php file on the server (Don't change me unless you have different PHP code)
 
  CURL *curl;
 
  CURLcode res;
 
  struct curl_httppost *formpost=NULL;
 
  struct curl_httppost *lastptr=NULL;
 
  struct curl_slist *headerlist=NULL;
 
  static const char buf[] = "Expect:";
 

	
 
  char *sjobnum;
 
  char *sframenum;
 
  char *sslavekey;
 

	
 
  fprintf(stderr,"Uploading to %s\n", url);
 

	
 
  _distren_asprintf(&sjobnum,"%d",jobnum);
 
  _distren_asprintf(&sframenum,"%d",framenum);
 
  _distren_asprintf(&sslavekey,"%d",slavekey);
 

	
 
  curl_global_init(CURL_GLOBAL_ALL);
 

	
 
  /* jobnum field... */
 
   curl_formadd(&formpost,
 
                &lastptr,
 
                CURLFORM_COPYNAME, "jobnum",
 
                CURLFORM_COPYCONTENTS, sjobnum, CURLFORM_END);
 
  /* framenum field... */
 
  curl_formadd(&formpost,
 
               &lastptr,
 
               CURLFORM_COPYNAME, "framenum",
 
               CURLFORM_COPYCONTENTS, sframenum, CURLFORM_END);
 
  /* slavekey field... */
 
  curl_formadd(&formpost,
 
               &lastptr,
 
               CURLFORM_COPYNAME, "slavekey",
 
               CURLFORM_COPYCONTENTS, sslavekey, CURLFORM_END);
 
  /* upload field... */
 
  curl_formadd(&formpost,
 
               &lastptr,
 
               CURLFORM_COPYNAME, targetname,
 
               CURLFORM_FILE, filename,
 
               CURLFORM_END);
 
  /* filename field... */
 
  curl_formadd(&formpost,
 
               &lastptr,
 
               CURLFORM_COPYNAME, "filename",
 
               CURLFORM_COPYCONTENTS, filename,
 
               CURLFORM_END);
 
  /* submit field, not usually needed, just in case... */
 
  curl_formadd(&formpost,
 
               &lastptr,
 
               CURLFORM_COPYNAME, "submit",
 
               CURLFORM_COPYCONTENTS, "send",
 
               CURLFORM_END);
 

	
 
  res = CURLE_FAILED_INIT;
 
  curl = curl_easy_init();
 
  headerlist = curl_slist_append(headerlist, buf);
 
  if(curl) {
 
  if(curl)
 
    {
 
    /* Setting the URL to get the post, and the contents of the post */
 
    curl_easy_setopt(curl, CURLOPT_URL, url);
 
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
 
    res = curl_easy_perform(curl);
 

	
 
    curl_easy_cleanup(curl);
 
    /* cleanup the formpost junk */
 
    curl_formfree(formpost);
 
    curl_slist_free_all (headerlist);
 
    free(sjobnum);
 
    free(sframenum);
 
    free(sslavekey);
 
  }
 
    }
 
  return res;
 
}
 

	
 

	
 
/** Logs the user into the server after ensuring that keys exist */
 
int login_user(char *username)
 
{
 
  // @TODO: Put some telnet-style auth code here unless this is obselete
 
  return 1; // success
 
}
 

	
 
/** Replaces wordtoreplace with replacewith in conffile (relative to SYSCONFDIR) */
 
int conf_replace(char *conffile, char *wordtoreplace, char *replacewith){
 
  int maxlinelen = 120;
 
  char *fileOrig;
 
  char *fileRepl;
 
  _distren_asprintf(&fileOrig, "%s/%s", SYSCONFDIR, conffile);
 
  _distren_asprintf(&fileRepl, "%s%s.edited", SYSCONFDIR, conffile);
 
  char buffer[maxlinelen+2];
 
  char *buff_ptr, *find_ptr;
 
  FILE *fp1, *fp2;
 
  size_t find_len = strlen(wordtoreplace);
 
  fp1 = fopen(fileOrig,"r");
 
  fp2 = fopen(fileRepl,"w");
 
@@ -613,61 +620,61 @@ int runBenchmark(int slavekey, char *dat
 
      _web_resetframe(slavekey, password, jobnum, framenum);  // Unassign the frame on the server so other slaves can render it
 
      return 1;
 
    }
 
  free(pathtoJobfile);
 

	
 
  struct stat buffer;
 
  int fstatus = stat(pathtoOutput, &buffer);
 
  if(fstatus == -1){
 
    fprintf(stderr,"*** Frame was not rendered correctly! Scene may not have camera, or your blender installation is not working.\n");
 
    _web_resetframe(slavekey, password, jobnum, framenum);  // Unassign the frame on the server so other slaves can render it
 
    return 1;
 
  }
 

	
 
}
 
*/
 

	
 
/* simpleSlave functions */
 

	
 
/** Memory struct for curl */
 
struct _web_memorystruct {
 
  char *memory;
 
  size_t size;
 
};
 

	
 
static void *_web_myrealloc(void *ptr, size_t size);
 
void *_web_myrealloc(void *ptr, size_t size);
 

	
 
static void *_web_myrealloc(void *ptr, size_t size)
 
void *_web_myrealloc(void *ptr, size_t size)
 
{
 
  /* There might be a realloc() out there that doesn't like reallocing
 
     NULL pointers, so we take care of it here */
 
  if(ptr)
 
    return realloc(ptr, size);
 
  else
 
    return malloc(size);
 
}
 

	
 
static size_t _web_writememorycallback(void *ptr, size_t size, size_t nmemb, void *data)
 
size_t _web_writememorycallback(void *ptr, size_t size, size_t nmemb, void *data)
 
{
 
  size_t realsize = size * nmemb;
 
  struct _web_memorystruct *mem = (struct _web_memorystruct *)data;
 

	
 
  mem->memory = _web_myrealloc(mem->memory, mem->size + realsize + 1);
 
  if (mem->memory) {
 
    memcpy(&(mem->memory[mem->size]), ptr, realsize);
 
    mem->size += realsize;
 
    mem->memory[mem->size] = 0;
 
  }
 
  return realsize;
 
}
 

	
 
struct _web_memorystruct _web_getrequest(char *url){
 
  // fprintf(stderr,"Preparing to get request at %s",url);
 

	
 
  CURL *curl;
 
  CURLcode res;
 
  struct _web_memorystruct chunk;
 

	
 
  chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
 
  chunk.size = 0;    /* no data at this point */
 

	
 
  curl = curl_easy_init();
src/server/slavefuncs.h
Show inline comments
 
@@ -3,66 +3,67 @@
 

	
 
  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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#ifndef _DISTREN_SLAVEFUNCS_H
 
#define _DISTREN_SLAVEFUNCS_H
 

	
 
#include "distrenjob.h"
 

	
 
#include "common/remoteio.h"
 

	
 
#include <curl/curl.h>
 
#include <libxml/xpath.h>
 
#include <stdio.h>
 

	
 

	
 
struct msg;
 
int sendSignal(struct remoteio *rem, char signal);
 
int sendExtSignal(struct remoteio *rem, char signal, char *data);
 
xmlNodePtr xml_quickxpath(xmlXPathContextPtr xpathctxt, xmlChar *path);
 
int software_updatecheck();
 
int delete_jobdata(int jobnum, char *datadir);
 
size_t curl_writetodisk(void *ptr, size_t size, size_t nmemb, FILE *stream);
 
int curlget(char *url, char *out);
 
int curlpost(char *filename, char *url, int jobnum, int framenum, int slavekey);
 
CURLcode curlget(char *url, char *out);
 
CURLcode curlpost(char *filename, char *url, int jobnum, int framenum, int slavekey);
 
int ssh_keygen();
 
int register_user(char *username, char *email);
 
int login_user(char *username);
 
int conf_replace(char *conffile, char *wordtoreplace, char *replacewith);
 
int exec_blender(char *input, char *output, int frame);
 
void xmlinit();
 
void xmlcleanup();
 
int distren_mkdir_recurse(char *dirname);
 
int job_build_path(char *filename, unsigned int jobnum);
 
int downloadTar(char *url, char *destinationPath);
 
int uploadOutput(char *pathtoOutput, char *urltoOutput, int jobnum, int framenum, int slavekey);
 
int unpackJob(char *outdir, char *pathtoTar);
 
void prepareJobPaths(int jobnum, int framenum, char *outputExt, char *datadir, char **urltoTar,char **pathtoTar,char **pathtoTardir,char **pathtoJob, char **pathtoJobfile,char **urltoJobfile,char **urltoOutput,char **pathtoOutput, char **pathtoRenderOutput, char **pathtoOutdir);
 
int checkUsername(char *username);
 
void slaveTest();
 

	
 
/* Simple slave */
 
struct _web_memorystruct;
 
static void *_web_myrealloc(void *ptr, size_t size);
 
static size_t _web_writememorycallback(void *ptr, size_t size, size_t nmemb, void *data);
 
void *_web_myrealloc(void *ptr, size_t size);
 
size_t _web_writememorycallback(void *ptr, size_t size, size_t nmemb, void *data);
 
struct _web_memorystruct _web_getrequest(char *url);
 
void _web_finishframe(int slavekey, char *slavepass, int jobnum, int framenum);
 
void _web_startframe(int slavekey, char *slavepass, int jobnum, int framenum);
 
void _web_resetframe(int slavekey, char *slavepass, int jobnum, int framenum);
 
int _web_getwork(int slavekey, char *slavepass, int *jobnum, int *framenum);
 
void _web_setrenderpower(int slavekey, char *slavepass, int renderpower);
 
int slaveBenchmark(char *datadir, int *benchmarkTime, int *renderPower);
 

	
 
#endif
0 comments (0 inline, 0 general)