/* files.c
 * v0.91
 *
 * Holger Danielsson
 * (dani@lara.prima.ruhr.de)
 * 6.9.1996
 *
 * Rainer Schnitker
 * add LFN support
 * Okt/96
 *
 */


#include <emx/syscalls.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>

static char *wildcard = "*.*";

static char *timestr( unsigned t, char *buf )
{
   sprintf( buf, "%2.2d:%2.2d", (t >> 11) & 0x1f, (t >> 5) & 0x3f);
   return buf;
}

static char *datestr( unsigned d, char *buf )
{
   sprintf( buf, "%2.2d-%2.2d-%2.2d", d&0x1f, (d>>5) & 0x0f, (d>>9) + 80 );
   return buf;
}

struct lfn_find_t {
  unsigned long lfn_handle;         /* find handle  */
  unsigned char lfn_attr;
  char magic[3];                    /* = "LFN"      */
  char shortname[13];		    /* DOS name     */

  unsigned char  attr;
  unsigned short time;
  unsigned short date;
  unsigned short size_lo;
  unsigned short size_hi;
  char name[257];
};

static long show_filename(struct _find *pfind)
{
   char timebuf[10], datebuf[10];
   char fname[_MAX_FNAME], ext[_MAX_EXT];
   char tmp[14];
   int lfn;
   char *shortname;
   unsigned size = ((unsigned) pfind->size_hi << 16) + pfind->size_lo;
   struct lfn_find_t *plfnfind = (struct lfn_find_t *) pfind;

   lfn = (memcmp(plfnfind->magic, "LFN", 3) == 0);

   if (lfn && *(plfnfind->shortname))
      shortname = plfnfind->shortname;
   else
      shortname = pfind->name;

   if (shortname[0] == '.' || shortname[1] == '.') {
       strcpy(fname, shortname);
       strcpy(ext, ".");
   }
   else {
       ext[1] = 0;
       _splitpath( shortname, NULL, NULL, fname, ext);
   }

   datestr( pfind->date, datebuf);
   timestr( pfind->time, timebuf);

   if (pfind->attr & (_A_SUBDIR | _A_VOLID))
      strcpy(tmp, "  <DIR>      ");
   else
      sprintf(tmp, "%13u", size);

   printf( "%-8s %-3s %s  %8s  %5s %s\n",
	   fname,
           ext + 1,
	   tmp,
	   datebuf,
	   timebuf,
	   (lfn) ? plfnfind->name : "");

   return size;
}

/* Verzeichnis wechseln
 *
 * Syntax: cd name
 * argv[]:     0
 */

int execute_cd(char *argv[])
{
   if ( argv[0] )
      _chdir2(argv[0]);
   return 0;
}

/* Laufwerk wechseln
 *
 * Syntax: drive pfad
 * argv[]:	 0
 */

int execute_drive(char *argv[])
{
   if (argv[0])
      _chdrive(argv[0][0]);
   return 0;
}


/* Inhalt eines Verzeichnisses ausgeben
 *
 * Syntax: dir
 *	   dir maske
 * argv[]:	 0
 */

int execute_dir(char *argv[])
{
   struct _find info;

   if ( argv[0]==0 )
      argv[0] = wildcard;

   if (__findfirst(argv[0],_A_NORMAL | _A_SUBDIR | _A_RDONLY, &info)) {
       puts("no files found");
       return 0;
   }
   show_filename(&info);
   while (__findnext(&info) == 0)
      show_filename(&info);
   return 0;
}

/* Dateien löschen
 *
 * Syntax: del name
 *	   del maske
 * argv[]:	 0
 */

int execute_del(char *argv[])
{
   if (! argv[0])
       return 0;

   if (strpbrk(argv[0],"*?")) {
      struct _find info;
      if (__findfirst(argv[0], _A_NORMAL, &info)) {
	 puts("no files found");
	 return 0;
      }
      else
	 remove(info.name);
      while (__findnext(&info) == 0)
	 remove(info.name);
      }
   else
       remove(argv[0]);
   return 0;
}

/* eine Datei umbenennen (ohne Wildcards)
 *
 * Syntax: rename alt neu
 * argv[]:	   0   1
 */

int execute_rename(char *argv[])
{
   if ( argv[0] && argv[1] )
      rename(argv[0],argv[1]);
   return 0;
}

/* ein neues Directory anlegen
 *
 * Syntax: mkdir name
 *	   md	 name
 * argv[]:	  0
 */

int execute_mkdir(char *argv[])
{
   if ( argv[0] ) {
      if ( access(argv[0],0)==0 )
	 puts("directory already exists");
      else
	 mkdir(argv[0],0);
   }
   return 0;
}

/* ein Directory löschen
 *
 * Syntax: rmdir name
 *	   rd	 name
 * argv[]:	  0
 */

int execute_rmdir(char *argv[])
{
   if ( argv[0] ) {
      if ( access(argv[0],0)==-1 )
	 puts("unknown directory");
      else
	 rmdir(argv[0]);
   }
   return 0;
}










