예제 #1
0
void cmd_rmdir(const char *name)
{
	const smbftpd_valid_share_t *share;
	char *real_path;
	real_path = smbftpd_get_realpath(smbftpd_session.valid_shares, name,
							   FLAG_CHECK_WRITABLE | FLAG_NO_FOLLOW_LINK);
	if (NULL == real_path) {
		reply_fs2client(550, "%s: Permission denied.", name);
		return;
	}

	if (smbftpd_session.mode == MODE_SMB) {
		share = smbftpd_get_share_by_path(smbftpd_session.valid_shares, real_path);
		if (!share || share->disable_modify) {
			reply_noformat(550, "Remove directory denied.");
			return;
		}
	}

	LOGCMD("rmdir", name);
	if (rmdir(real_path) < 0)
		reply_fs2client(550, "%s: %s.", name, strerror(errno));
	else
		reply_noformat(250, "RMD command successful.");
}
예제 #2
0
void cmd_delete(const char *path)
{
    const smbftpd_valid_share_t *share;
    struct stat st;
    char *real_path;

    real_path = smbftpd_get_realpath(smbftpd_session.valid_shares, path,
                                     FLAG_NO_FOLLOW_LINK | FLAG_CHECK_WRITABLE);

    if (NULL == real_path) {
        reply_fs2client(550, "%s: permission denied.", path);
        return;
    }

    if (smbftpd_session.mode == MODE_SMB) {
        share = smbftpd_get_share_by_path(smbftpd_session.valid_shares, real_path);
        if (!share || share->disable_modify) {
            reply_noformat(550, "Delete file denied.");
            return;
        }
    }

    LOGCMD("delete", path);
    if (lstat(real_path, &st) < 0) {
        reply_fs2client(550, "%s: %s.", path, strerror(errno));
        return;
    }
    if (S_ISDIR(st.st_mode)) {
        if (rmdir(real_path) < 0) {
            reply_fs2client(550, "%s: %s.", path, strerror(errno));
            return;
        }
        goto done;
    }
    if (unlink(real_path) < 0) {
        reply_fs2client(550, "%s: %s.", path, strerror(errno));
        return;
    }
done:
    reply_noformat(250, "DELE command successful.");
}
예제 #3
0
void
store (const char *name, const char *mode, int unique)
{
  FILE *fout, *din;
  struct stat st;
  int (*closefunc) (FILE *);

  if (unique && stat (name, &st) == 0)
    {
      const char *name_unique = gunique (name);
      
      if (name_unique)
        name = name_unique;
      else
        {
          LOGCMD (*mode == 'w' ? "put" : "append", name);
          return;
        }
    }

  if (restart_point)
    mode = "r+";
  fout = fopen (name, mode);
  closefunc = fclose;
  if (fout == NULL)
    {
      perror_reply (553, name);
      LOGCMD (*mode == 'w' ? "put" : "append", name);
      return;
    }
  byte_count = -1;
  if (restart_point)
    {
      if (type == TYPE_A)
	{
	  off_t i, n;
	  int c;

	  n = restart_point;
	  i = 0;
	  while (i++ < n)
	    {
	      c = getc (fout);
	      if (c == EOF)
		{
		  perror_reply (550, name);
		  goto done;
		}
	      if (c == '\n')
		i++;
	    }
	  /* We must do this seek to "current" position
	     because we are changing from reading to
	     writing.  */
	  if (fseek (fout, 0L, SEEK_CUR) < 0)
	    {
	      perror_reply (550, name);
	      goto done;
	    }
	}
      else if (lseek (fileno (fout), restart_point, SEEK_SET) < 0)
	{
	  perror_reply (550, name);
	  goto done;
	}
    }
  din = dataconn (name, (off_t) - 1, "r");
  if (din == NULL)
    goto done;
  if (receive_data (din, fout) == 0)
    {
      if (unique)
	reply (226, "Transfer complete (unique file name:%s).", name);
      else
	reply (226, "Transfer complete.");
    }
  fclose (din);
  data = -1;
  pdata = -1;
done:
  LOGBYTES (*mode == 'w' ? "put" : "append", name, byte_count);
  (*closefunc) (fout);
}
예제 #4
0
void
retrieve (const char *cmd, const char *name)
{
  FILE *fin, *dout;
  struct stat st;
  int (*closefunc) (FILE *);
  size_t buffer_size = 0;

  if (cmd == 0)
    {
      fin = fopen (name, "r"), closefunc = fclose;
      st.st_size = 0;
    }
  else
    {
      char line[BUFSIZ];

      snprintf (line, sizeof line, cmd, name);
      name = line;
      fin = ftpd_popen (line, "r"), closefunc = ftpd_pclose;
      st.st_size = -1;
      buffer_size = BUFSIZ;
    }

  if (fin == NULL)
    {
      if (errno != 0)
	{
	  perror_reply (550, name);
	  if (cmd == 0)
	    {
	      LOGCMD ("get", name);
	    }
	}
      return;
    }
  byte_count = -1;
  if (cmd == 0 && (fstat (fileno (fin), &st) < 0 || !S_ISREG (st.st_mode)))
    {
      reply (550, "%s: not a plain file.", name);
      goto done;
    }
  if (restart_point)
    {
      if (type == TYPE_A)
	{
	  off_t i, n;
	  int c;

	  n = restart_point;
	  i = 0;
	  while (i++ < n)
	    {
	      c = getc (fin);
	      if (c == EOF)
		{
		  perror_reply (550, name);
		  goto done;
		}
	      if (c == '\n')
		i++;
	    }
	}
      else if (lseek (fileno (fin), restart_point, SEEK_SET) < 0)
	{
	  perror_reply (550, name);
	  goto done;
	}
    }
  dout = dataconn (name, st.st_size, "w");
  if (dout == NULL)
    goto done;
  send_data (fin, dout, buffer_size);
  fclose (dout);
  data = -1;
  pdata = -1;
done:
  if (cmd == 0)
    LOGBYTES ("get", name, byte_count);
  (*closefunc) (fin);
}