Example #1
0
// main client handler procedure, runs in its own thread
void * thread_proc(void * param)
{
	CLIENT_INFO client_info;
	memset(&client_info, 0, sizeof(client_info));
	client_info.fd = (int)param;
	strcpy(client_info.dir, "/");

	send_code(client_info.fd, 220);

	while (1)
	{
		int result = client_read(client_info.fd, client_info.buf, &client_info.buffer_pos);
		if (result == -1) break;

		while (client_info.buffer_pos >= 4)
		{
			char line[BUFFER_SIZE] = { 0 };

			if (compare_command(client_info.buf, "USER")) command_user(&client_info);
			else if (compare_command(client_info.buf, "PASS")) command_pass(&client_info);
			else if (compare_command(client_info.buf, "PWD")) command_pwd(&client_info);
			else if (compare_command(client_info.buf, "PORT")) command_port(&client_info);
			else if (compare_command(client_info.buf, "PASV")) command_pasv(&client_info);
			else if (compare_command(client_info.buf, "LIST")) command_list(&client_info);
			else if (compare_command(client_info.buf, "CWD")) command_cwd(&client_info);
			else if (compare_command(client_info.buf, "RETR")) command_retr(&client_info);
			else if (compare_command(client_info.buf, "NOOP")) command_noop(&client_info);
			else if (compare_command(client_info.buf, "SYST")) command_syst(&client_info);
			else if (compare_command(client_info.buf, "TYPE")) command_type(&client_info);
			else if (compare_command(client_info.buf, "QUIT"))
			{
				get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos);
				send_code(client_info.fd, 221);
				close(client_info.fd);
				client_info.fd = 0;
				return NULL;
			}
			else
			{
				get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos);
				send_code(client_info.fd, 500);
			}
		}
	}

	if (client_info.fd != 0)
	{
		close(client_info.fd);
		client_info.fd = 0;
	}

	return NULL;
}
Example #2
0
/*PAGE
 *
 * exec_command
 *
 * Parse and execute FTP command.
 *
 * FIXME: This section is somewhat of a hack.  We should have a better
 *        way to parse commands.
 *
 * Input parameters:
 *   info - corresponding SessionInfo structure
 *   cmd  - command to be executed (upper-case)
 *   args - arguments of the command
 *
 * Output parameters:
 *    NONE
 */
static void
exec_command(FTPD_SessionInfo_t *info, char* cmd, char* args)
{
  char fname[FTPD_BUFSIZE];
  int wrong_command = 0;

  fname[0] = '\0';

  if (!strcmp("PORT", cmd))
  {
    command_port(info, args);
  }
  else if (!strcmp("PASV", cmd))
  {
    command_pasv(info);
  }
  else if (!strcmp("RETR", cmd))
  {
    strncpy(fname, args, 254);
    command_retrieve(info, fname);
  }
  else if (!strcmp("STOR", cmd))
  {
    strncpy(fname, args, 254);
    command_store(info, fname);
  }
  else if (!strcmp("LIST", cmd))
  {
    strncpy(fname, args, 254);
    command_list(info, fname, 1);
  }
  else if (!strcmp("NLST", cmd))
  {
    strncpy(fname, args, 254);
    command_list(info, fname, 0);
  }
  else if (!strcmp("MDTM", cmd))
  {
    strncpy(fname, args, 254);
    command_mdtm(info, fname);
  }
  else if (!strcmp("SYST", cmd))
  {
    send_reply(info, 215, FTPD_SYSTYPE);
  }
  else if (!strcmp("TYPE", cmd))
  {
    if (args[0] == 'I')
    {
      info->xfer_mode = TYPE_I;
      send_reply(info, 200, "Type set to I.");
    }
    else if (args[0] == 'A')
    {
      info->xfer_mode = TYPE_A;
      send_reply(info, 200, "Type set to A.");
    }
    else
    {
      info->xfer_mode = TYPE_I;
      send_reply(info, 504, "Type not implemented.  Set to I.");
    }
  }
  else if (!strcmp("USER", cmd) || !strcmp("PASS", cmd))
  {
    send_reply(info, 230, "User logged in.");
  }
  else if (!strcmp("DELE", cmd))
  {
    if(!can_write())
    {
      send_reply(info, 550, "Access denied.");
    }
    else if (
      strncpy(fname, args, 254) &&
      unlink(fname) == 0)
    {
      send_reply(info, 257, "DELE successful.");
    }
    else
    {
      send_reply(info, 550, "DELE failed.");
    }
  }
  else if (!strcmp("SITE", cmd))
  {
    char* opts;
    split_command(args, &cmd, &opts, &args);
    if(!strcmp("CHMOD", cmd))
    {
      int mask;

      if(!can_write())
      {
        send_reply(info, 550, "Access denied.");
      }
      else {
        char *c;
        c = strchr(args, ' ');
        if((c != NULL) && (sscanf(args, "%o", &mask) == 1) && strncpy(fname, c+1, 254) 
          && (chmod(fname, (mode_t)mask) == 0))
          send_reply(info, 257, "CHMOD successful.");
        else
          send_reply(info, 550, "CHMOD failed.");
      }
    }
    else
      wrong_command = 1;
  }
  else if (!strcmp("RMD", cmd))
  {
    if(!can_write())
    {
      send_reply(info, 550, "Access denied.");
    }
    else if (
      strncpy(fname, args, 254) &&
      rmdir(fname) == 0)
    {
      send_reply(info, 257, "RMD successful.");
    }
    else
    {
      send_reply(info, 550, "RMD failed.");
    }
  }
  else if (!strcmp("MKD", cmd))
  {
    if(!can_write())
    {
      send_reply(info, 550, "Access denied.");
    }
    else if (
      strncpy(fname, args, 254) &&
      mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0)
    {
      send_reply(info, 257, "MKD successful.");
    }
    else
    {
      send_reply(info, 550, "MKD failed.");
    }
  }
  else if (!strcmp("CWD", cmd))
  {
    strncpy(fname, args, 254);
    command_cwd(info, fname);
  }
  else if (!strcmp("CDUP", cmd))
  {
    command_cwd(info, "..");
  }
  else if (!strcmp("PWD", cmd))
  {
    command_pwd(info);
  }
  else
    wrong_command = 1;

  if(wrong_command)
    send_reply(info, 500, "Command not understood.");
}