/*****************************************************************************\
* Copyright (c) 2002 Pelle Johansson.                                         *
* All rights reserved.                                                        *
*                                                                             *
* This file is part of the moftpd package. Use and distribution of            *
* this software is governed by the terms in the file LICENCE, which           *
* should have come with this package.                                         *
\*****************************************************************************/

/* $moftpd: com_navigation.c 1251 2005-03-06 22:24:29Z morth $ */

#include "system.h"

#include "commands.h"

#include "connection.h"
#include "utf8fs/memory.h"

/* Navigation commands */

int command_cwd(connection_t *conn, const char *arg, int expected)
{
  if(!strlen(arg))
    reply(conn, "501 Path missing.");
  else
  {
    const char *ncwd;
    
    ncwd = set_cwd (chroot_path (arg, conn->cwd, conn->user?
          conn->user->home : NULL), NULL);
    if (ncwd)
    {
      int common = 0;
      
      if (conn->cwd)
      {
	for (; ncwd[common] && ncwd[common] == conn->cwd[common]; common++)
	  ;
	if (conn->cwd[common] && conn->cwd[common] != '/')
	  while (ncwd[--common] != '/')
	    ;
      }
      while (ncwd[common] == '/')
	common++;
      
      while (ncwd[common])
      {
	char tmp[4097];
	const char *rmfn;
	int one = 0;
	
	rmfn = strchr (ncwd + common, '/');
	if (rmfn)
	  common = rmfn - ncwd + 1;
	else
	  common = strlen (ncwd);
	
	strncpy (tmp, ncwd, common);
	if (common < 4096 && tmp[common - 1] != '/')
	  tmp[common + one++] = '/';
	tmp[common + one] = 0;
	rmfn = dir_msg_file (tmp);
	if (!rmfn)
	  rmfn = conn->user->dirMsgFile;
	if (rmfn && common + one + strlen (rmfn) < 4097)
	{
	  strcpy (tmp + common + one, rmfn);
	  reply_file (conn, "250-%s", tmp, NULL);
	}
      }
      pfree (conn->cwd, conn);
      conn->cwd = pstring (ncwd, conn);
      
      reply (conn, "250 \"%s\" is current directory.", print_path (conn->cwd));
    }
    else
      reply(conn, "550 %s.", strerror(errno));
  }
  return 0;
}

int command_cdup(connection_t *conn, const char *arg, int expected)
{
  return command_cwd(conn, "..", 0);
}

int command_smnt(connection_t *conn, const char *arg, int expected)
{
  /*
   * I suppose things like different drive letters in Windows and similar
   * systems should go here, but I've never seen any client implementing this
   * command.
   * Make SMNT <device> an alias for CWD <mount point> perhaps?
   */
  reply(conn, "502 Only one structure on this host.");
  return 0;
}

int command_pwd(connection_t *conn, const char *arg, int expected)
{
  reply (conn, "257 \"%s\" is current directory.", print_path (conn->cwd));
  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1