Commit 4812fb2e authored by Seblu's avatar Seblu
Browse files

General improvment

parent 87c158ca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
Improvments
command update
remove static magic MAX_LINE_SIZE in sscanf

BUG:
+74 −94
Original line number Diff line number Diff line
@@ -18,11 +18,6 @@

#include "sld.hh"

const string VERSION = "1";
const int MAX_LINE_SIZE = 512;
const char *RCV_DATA = "<< ";
const char *SND_DATA = ">> ";

SLDaemon *SLDaemon::instance_ = 0;

SLDaemon::SLDaemon() : socket_fs_(0) {}
@@ -174,7 +169,7 @@ void SLDaemon::run() {
  auth();
  while (1) {
    line = recvln();
    tee(line, RCV_DATA);
    warn(line, RCV_DATA);
    // call right handler
    try {
      if (!strcmp(line, "EXIT\n"))
@@ -191,7 +186,7 @@ void SLDaemon::run() {
	cmd_killall();
      else if (!strcmp(line, "KILL\n"))
	cmd_kill(line);
      else if (!strncmp(line, "JOB ", 5))
      else if (!strncmp(line, "JOB ", 4))
	cmd_job(line);
      else if (!strncmp(line, "FILE ", 5))
	cmd_file(line);
@@ -345,19 +340,30 @@ void SLDaemon::auth() {
  return;
}

void SLDaemon::tee(const string &msg, const string &local_prefix) {
void SLDaemon::answer(const string &msg, bool prefix) {
  if (verbose())
    std::cout << (prefix ? SND_DATA : "") << msg;
  send(msg);
}

void SLDaemon::answer(long int i, bool prefix) {
  if (verbose()) std::cout << (prefix ? SND_DATA : "") << i;
  send(i);
}

void SLDaemon::warn(const string &msg, const string &prefix) {
  if (verbose())
    std::cout << local_prefix << msg;
    std::cout << SND_DATA << prefix << msg;
  send(msg);
}

void SLDaemon::tee(long int i) {
  if (verbose()) std::cout << i;
void SLDaemon::warn(long int i, const string &prefix) {
  if (verbose()) std::cout << prefix << i;
  send(i);
}

void SLDaemon::proto_violation() {
  tee("sld: Protocol violation.\n");
  answer("sld: Protocol violation.\n");
}


@@ -367,64 +373,60 @@ void SLDaemon::proto_violation() {
//******************************************************************************

void SLDaemon::cmd_exit() {
  if (verbose())
    std::cout << "EXIT requested." << std::endl;
  send("Bye.\n");
  answer("BYE\n");
  disconnect();
  exit(ERR_OK);
}

void SLDaemon::cmd_version() {
  if (verbose())
    std::cout << "VERSION requested." << std::endl;
  send(VERSION);
  send("\n");
  answer(VERSION + "\n");
}

void SLDaemon::cmd_job(const char *line) {
  assert(line);

  // build path
  //FIXME: Bad static magic number
  char filename[512];
  sscanf(line, "JOB %s\n", filename);
  string path = options_.scriptdir + "/" +  filename;
  char buf[MAX_LINE_SIZE];
  sscanf(line, "JOB %512s\n", buf);  //FIXME: Bad static magic number
  string path = options_.scriptdir + "/" +  buf;

  // Check if file exist
  struct stat st;
  int ret = lstat(path.c_str(), &st);
  if (ret == ENOENT || errno == EACCES) {
    tee(strerror(errno), SND_DATA);
    answer((string) "JOB: " + strerror(errno) + ".\n");
    return;
  }
  // check for exec flag
  if (st.st_mode | S_IXUSR != S_IXUSR) {
    tee("JOB: no exec flag.\n", SND_DATA);
  if (st.st_mode | S_IXUSR != S_IXUSR) { //FIXME: mask error !
    answer("JOB: no exec flag.\n");
    return;
  }
  // check file owner
  if (st.st_uid != getuid()) {
    tee("JOB: Bad file owner.\n", SND_DATA);
    answer("JOB: Bad file owner.\n");
    return;
  }

  // Create new process
  flush();
  pid_t pid = fork();
  if (pid == -1)
    throw Error(ERR_NET, "Unable to fork");
  if (pid == -1) {
    answer((string) "JOB: Unable to fork: " + strerror(errno) + ".\n");
    return;
  }

  // Father job
  if (pid > 0) {
    // reg job
    SLDaemon::Job j(pid, filename, time(0));
    SLDaemon::Job j(pid, buf, time(0));
    jobs_.insert(j);
    
    // show job info
    tee((string) "JOB: " + filename + ", pid: ", SND_DATA);
    tee(pid);
    tee(", start at: ");
    tee(j.start_time);
    tee("\n");
    // send job info
    snprintf(buf, MAX_LINE_SIZE,
	     "JOB: %s, pid: %d, start at: %ld.\n",
	     j.name.c_str(), j.pid, j.start_time);
    answer(buf);
  }
  // Son job
  else if (pid == 0) {
@@ -450,8 +452,8 @@ void SLDaemon::cmd_file(const char *line) {
  assert(line);

  // get filename
  char filename[512]; //FIXME: bad magic size
  if (sscanf(line, "FILE %512s\n", filename) != 1) {
  char filename[MAX_LINE_SIZE];
  if (sscanf(line, "FILE %512s\n", filename) != 1) { //FIXME: bad magic size
    proto_violation();
    return;
  }
@@ -460,38 +462,32 @@ void SLDaemon::cmd_file(const char *line) {
  //get size
  int size;  
  buf = recvln();
  warn(buf);
  ret = sscanf(buf, "SIZE %i\n", &size);
  delete buf;
  if (ret != 1) {
    tee("Invalid size parameter."); 
    answer("FILE: Invalid size parameter.\n"); 
    return;
  }
  
  //get md5
  char md5[512]; //FIXME: bad magic size
  char md5[MAX_LINE_SIZE]; 
  buf = recvln();
  ret = sscanf(buf, "MD5 %512s\n", md5);
  warn(buf);
  ret = sscanf(buf, "MD5 %512s\n", md5); //FIXME: bad magic size
  delete buf;
  if (ret != 1) {
    tee("Invalid md5 parameter.");
    answer("FILE: Invalid md5 parameter.\n");
    return;
  }

  // show verbose
  if (verbose())
    std::cout << "FILE transfer requested: "
	      << "to=" << target
	      << ", size=" << size
	      << ", md5=" << md5 << "."
	      << std::endl;

  //get data
  try {
    recv(size, target);
  }
  catch (const Error &err) {
    if (err.code() == ERR_FILE) {
      tee("Data transfer error.");
      answer("FILE: Data transfer error.\n");
      return;
    }
    throw;
@@ -499,38 +495,36 @@ void SLDaemon::cmd_file(const char *line) {

  // check MD5
  if (SLDaemon::md5(target) != string(md5)) {
    tee("Transfer of " + target + ": Invalid MD5.");
    answer("FILE: file " + target + ": Invalid MD5.\n");
    unlink(target.c_str());
    return;
 }

  // proceed chown
  if (chown(target.c_str(), getuid(), getgid())) {
    tee("chown of " + target + ": Unable to chown.");
    answer("FILE: chown of " + target + ": Unable to chown.\n");
    unlink(target.c_str());
    return;
  }

  // proceed chmod
  if (chmod(target.c_str(), S_IRUSR | S_IWUSR | S_IXUSR)) {
    tee("chmod of " + target + ": Unable to chmod.");
    answer("FILE: chmod of " + target + ": Unable to chmod.\n");
    unlink(target.c_str());
    return;
  }

  tee("Transfer of " + target + ": OK."); 
  answer("FILE: Transfer of " + target + ": OK.\n"); 
}
 
void SLDaemon::cmd_update(const char *line) {
  assert(line);
  if (verbose())
    std::cout << "UPDATE requested." << std::endl;
}

void SLDaemon::cmd_list() {
  FILE *fls = popen(string("ls -1A " + options_.scriptdir).c_str(), "r");
  if (fls == 0) {
    tee("LIST: Unable to list " + options_.scriptdir + ".\n", SND_DATA);
    answer("LIST: Unable to list " + options_.scriptdir + ".\n");
    return;
  }

@@ -540,6 +534,7 @@ void SLDaemon::cmd_list() {
    while ((len = fread(buf, 1, 255, fls)) > 0)
      send(buf, len);
    flush();
    warn("LIST: data send.\n");
  }
  catch (...) {
    pclose(fls);
@@ -550,24 +545,21 @@ void SLDaemon::cmd_list() {
void SLDaemon::cmd_status() {
  t_job::iterator i;
  time_t t = time(0);
  char buf[MAX_LINE_SIZE];

  tee("STATUS of \n", SND_DATA);
  answer("STATUS of \n");
  for (i = jobs_.begin(); i != jobs_.end(); ++i) {
    tee("job: ", SND_DATA);
    tee(i->name);
    tee(", pid: ");
    tee(i->pid);
    tee(", start at: ");
    tee(i->start_time);
    tee(", since: ");
    tee(t - i->start_time);
    tee(" seconds.\n");
    snprintf(buf, MAX_LINE_SIZE,
	     " job: %s, pid: %d, start at: %ld, since: %ld seconds.\n",
	     i->name.c_str(), i->pid, i->start_time,t - i->start_time);
    answer(buf);
  }
  flush();
}

void SLDaemon::cmd_kill(const char *line) {
  t_job::iterator i;
  char buf[MAX_LINE_SIZE];

  // retrieve pid
  int pid;
@@ -579,35 +571,22 @@ void SLDaemon::cmd_kill(const char *line) {
  for (i = jobs_.begin(); i != jobs_.end(); ++i)
    if (pid == i->pid) {
      int ret = kill(i->pid, SIGKILL);
      send("kill -SIGKILL ");
      send(i->pid);
      send(" (");
      send(i->name);
      send(") => ");
      if (ret == -1)
	send(strerror(errno));
      else
	send("0");
      send("\n");
      snprintf(buf, MAX_LINE_SIZE, "KILL: kill -SIGKILL %d (%s), return %d (%s).\n",
	       i->pid, i->name.c_str(), ret, ((ret == -1) ? strerror(errno) : "OK" ));
      answer(buf);
    }
  flush();
}

void SLDaemon::cmd_killall() {
  t_job::iterator i;
  char buf[MAX_LINE_SIZE];

  for (i = jobs_.begin(); i != jobs_.end(); ++i) {
    int ret = kill(i->pid, SIGKILL);
    send("kill -SIGKILL ");
    send(i->pid);
    send(" (");
    send(i->name);
    send(") => ");
    if (ret == -1)
      send(strerror(errno));
    else
      send("0");
    send("\n");
    snprintf(buf, MAX_LINE_SIZE, "KILL: kill -SIGKILL %d (%s), return %d (%s).\n",
	     i->pid, i->name.c_str(), ret, ((ret == -1) ? strerror(errno) : "OK" ));
    answer(buf);
  }
  flush();
}
@@ -616,14 +595,14 @@ void SLDaemon::cmd_reload() {
  const char *path = binpath();

  if (path == NULL) {
    tee("RELOAD: Unable to locate sld binary.\n", SND_DATA);
    answer("RELOAD: Unable to locate sld binary.\n");
    return;
  }
  
  // Get bin info
  struct stat st;
  if (lstat(path, &st)) {
    tee((string)"RELOAD: lstat: " + strerror(errno) + "\n", SND_DATA);
    answer((string)"RELOAD: lstat: " + strerror(errno) + ".\n");
    return;
  }
  
@@ -631,7 +610,7 @@ void SLDaemon::cmd_reload() {
  
  int pid = fork();
  if (pid == -1) {
    tee((string)"RELOAD: " + strerror(errno) + "\n", SND_DATA);
    answer((string)"RELOAD: " + strerror(errno) + ".\n");
    return;
  }
  // father process
@@ -642,7 +621,7 @@ void SLDaemon::cmd_reload() {
  // son process
  else {
    execl(path, basename(path));
    tee((string) "RELOAD: " + strerror(errno) + "\n", SND_DATA);
    answer((string) "RELOAD: " + strerror(errno) + ".\n");
    flush();
    exit(ERR_UNKNOWN);
  }
@@ -680,7 +659,7 @@ string SLDaemon::md5(const string &file) const {
// Class Job functions
//******************************************************************************

SLDaemon::Job::Job(int p, string s, time_t t) : pid(p), name(s), start_time(t) {}
SLDaemon::Job::Job(int p, const string &s, time_t t) : pid(p), name(s), start_time(t) {}

bool SLDaemon::Job::operator()(const SLDaemon::Job &a, const SLDaemon::Job &b) {
  return a.pid < b.pid;
@@ -704,12 +683,13 @@ void sigchild(int) {
    for (i = jobs_.begin(); i != jobs_.end(); ++i) {
      if (i->pid == pid) {
	char buf[MAX_LINE_SIZE];
    
	snprintf(buf, MAX_LINE_SIZE,
		 "JOB: %s, pid: %d, end at: %ld, since: %ld, return: %d\n",
		 i->name.c_str(), i->pid,  t, t - i->start_time,
		 WEXITSTATUS(status));
	write(d.socket_fd_, buf, strlen(buf));
	if (d.verbose())
	  std::cout << SND_DATA << buf;
	jobs_.erase(i);
	break;
      }
+9 −9
Original line number Diff line number Diff line
@@ -35,12 +35,10 @@ enum {
// Gonstant
// -----------------------------------------------------------------------------

extern const string VERSION;
extern const int MAX_LINE_SIZE;
extern const char *RCV_DATA;
extern const char *SND_DATA;


static const string VERSION = "1";
static const int MAX_LINE_SIZE = 512;
static const string RCV_DATA = "<< ";
static const string SND_DATA = ">> ";

void sigchild(int);

@@ -69,7 +67,7 @@ public:

  struct Job {
    Job() {}
    Job(int, string, time_t);
    Job(int, const string &, time_t);
    int pid;
    string name;
    time_t start_time;
@@ -117,8 +115,10 @@ protected:
  
  // protocol functions
  void auth();
  void tee(const string &msg, const string &local_prefix = "");
  void tee(long int);
  void answer(const string &, bool = true);
  void answer(long int, bool = true);
  void warn(const string &, const string & = "");
  void warn(long int, const string & = "");
  void proto_violation();
  
  // commmand functions