/* 
   Unix SMB/Netbios implementation.
   Version 1.9.
   Copyright (C) Andrew Tridgell 1994-1997

   This file is part of the port to OpenVMS
   Directory routines.
   Copyright (C) Eckart Meyer 1996-1997
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*	dir.c
 *				5-Aug-1995	IfN/Mey
 *
 *	Derived from a module from P Kay's UNIXSHR.
 *
 *	Modified by Eckart Meyer, meyer@ifn.ing.tu-bs.de
 *+
 * opendir, readdir, seekdir and closedir.
 *-
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <lib$routines.h>
#include <ssdef.h>
#include <rmsdef.h>
#include <errno.h>

#ifndef __UNISTD_LOADED
char *getcwd (char *__buffer, unsigned int __size);
#endif

int samba_chdir   (char *__dir_spec);	/* SAMBA */
#define ChDir samba_chdir

struct _dirdesc {
 int dd_fd;
 long dd_loc;
 long dd_size;
 long dd_bbase;
 long dd_entno;
 long dd_bsize;
 char *dd_buf;
};

/*
 * readdir() should return files relative to the path specified by
 * opendir(). For this reason we have to chdir() to that directory
 * before calling SYS$FIND_FILE. When called often and with large
 * directories this decreases performance significantly.
 *
 * If you are sure that chdir() is not called from other places between
 * calls to opendir() and closedir() and that your application does not
 * care about a default directory change, you may define FAST_READDIR.
 * This way, chdir() is only called once in opendir() and again in closedir()
 * to change the default directory back to the saved path.
 */

#define FAST_READDIR	/**/

/*
 * If the filename should be returned in all lowercase
 */
#define MAKE_LOWERCASE	/**/

static DIR directory;
static struct dirent dp;
static char *wild = "*.*;0";
static char path[256];
static char resfile[256];
static char save_path[256];

#if 1	/* for use with samba's debugging */	/* SAMBA */
extern int DEBUGLEVEL;
#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
int Debug1();
#else
int DEBUGLEVEL = 8;
#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(printf body):0)
#endif

char *vms_get_name(char * __name);		/* SAMBA */
char *vms_make_name(char * __name);		/* SAMBA */

DIR *vms_opendir(filename)
char *filename;
{
  DEBUG (4,("opendir: \"%s\"\n",filename));
  if (strlen(filename) > 250) {
    errno = ENAMETOOLONG;
    return(NULL);
  }
  path[0] = '\0';
  if (filename[0] != '/'  &&  filename[0] != '.') strcpy(path,"./"); /* SAMBA */
  strcat(path,filename); /**/
/*  strcat(path,vms_make_name(filename));		/* SAMBA */
if (strcmp(path,"./") == 0) strcpy(path,".");
  DEBUG(8,("   path: \"%s\"\n",path));
  directory.dd_loc = 0;
#ifdef FAST_READDIR
  getcwd(save_path,256);
  DEBUG(8,("   save_path: \"%s\"\n",save_path));
  if (ChDir(path) < 0) return(NULL);
#endif
  {char x[256];DEBUG (8,("++++getcwd: \"%s\"\n",getcwd(x,256)));} /**/
  return(&directory);
}

struct dirent *vms_readdir(dirp)
DIR *dirp;
{
  int st;
  char *p, *q, *e = NULL;
  struct {
     int length;
     char *ptr;
  } filedesc, res_filedesc;
  filedesc.length = strlen(wild);
  filedesc.ptr = wild;
  res_filedesc.length = 256;
  res_filedesc.ptr = resfile;
#ifndef FAST_READDIR
  getcwd(save_path,256);
  if (ChDir(path) < 0) return(NULL);
#endif
  DEBUG (8,("readdir: saved path = \"%s\", path = \"%s\"\n",save_path,path)); /**/
  {char x[256];DEBUG (8,("++++getcwd: \"%s\"\n",getcwd(x,256)));} /**/
  st = lib$find_file(&filedesc,&res_filedesc,&directory.dd_loc,0,0,0,0);
#ifndef FAST_READDIR
  ChDir(save_path);
#endif
  if (st == SS$_NORMAL || st == RMS$_NORMAL) {
     for (p = res_filedesc.ptr;*p != ']';p++);	/* point behind directory */
     p++;
     p = vms_get_name(p);			/* SAMBA */
     for (q = dp.d_name, p; *p != ';'; q++ ,p++){
       *q = *p;
       if (*p == '.') e = q;	/* remember start of extension */
#ifdef MAKE_LOWERCASE
       if ( *q >= 'A' && *q <= 'Z') *q = *q -'A'+'a';
#endif
     }
     *q = '\0';
     if (e == NULL) e = q;	/* no extension found */
     if (strcmp(e,".dir") == 0) *e = '\0';	/* SAMBA - remove .DIR */
     if (strcmp(e,".") == 0) *e = '\0';		/* SAMBA - remove single dot */
     DEBUG (8,("readdir: extension: \"%s\"\n",e));
/*     dp.d_namlen = strlen(dp.d_name); /**/
     DEBUG (3,("readdir: returns \"%s\"\n",dp.d_name));
     return(&dp);
  }
  if (st == RMS$_NMF) return(NULL);	/* don't touch errno if no more files */
  errno = ENOENT;
  if (st == SS$_NOPRIV) errno = EACCES;
  return(NULL);
}

int vms_closedir(dirp)
DIR *dirp;
{
  lib$find_file_end(&directory.dd_loc);
#ifdef FAST_READDIR
  ChDir(save_path);
#endif
  return(0);
}

void vms_rewinddir(dirp)
DIR *dirp;
{
/* sorry no time to do this properly */
}
