2011-11-13 00:38:57 +01:00
|
|
|
/* namspace.c 17-Jul-96 : NameSpace Services, mars_nwe */
|
2011-11-13 00:38:55 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */
|
|
|
|
/* Its very dirty till now. */
|
|
|
|
/* namespace calls should be only activated for testings */
|
|
|
|
|
|
|
|
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
2011-11-13 00:38:55 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "net.h"
|
2011-11-13 00:38:55 +01:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <utime.h>
|
2011-11-13 00:38:56 +01:00
|
|
|
#ifndef LINUX
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "nwvolume.h"
|
2011-11-13 00:38:55 +01:00
|
|
|
#include "connect.h"
|
2011-11-13 00:38:56 +01:00
|
|
|
#include "nwfile.h"
|
2011-11-13 00:38:56 +01:00
|
|
|
#include "unxfile.h"
|
2011-11-13 00:38:55 +01:00
|
|
|
#include "namspace.h"
|
2011-11-13 00:38:55 +01:00
|
|
|
|
2011-11-13 00:38:55 +01:00
|
|
|
#if WITH_NAME_SPACE_CALLS
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
#define NW_PATH /* */
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int volume; /* Volume Number */
|
|
|
|
int has_wild; /* fn has wildcards */
|
2011-11-13 00:38:57 +01:00
|
|
|
int namespace; /* which namespace do we use here*/
|
2011-11-13 00:38:56 +01:00
|
|
|
struct stat statb; /* stat buff */
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 *fn; /* points to last entry of path */
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 path[512]; /* path + fn */
|
2011-11-13 00:38:56 +01:00
|
|
|
} N_NW_PATH;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
DIR *fdir; /* for dir searches */
|
|
|
|
uint8 *kpath; /* points one after unixname */
|
|
|
|
uint8 *unixname; /* is allocates fullname of path */
|
2011-11-13 00:38:56 +01:00
|
|
|
/* + 257 Byte for filename. */
|
2011-11-13 00:38:56 +01:00
|
|
|
} DIR_SEARCH_STRUCT;
|
|
|
|
|
|
|
|
typedef struct {
|
2011-11-13 00:38:56 +01:00
|
|
|
uint32 basehandle;
|
|
|
|
int slot; /* act slot in table */
|
|
|
|
int locked; /* if locked then do not remove */
|
2011-11-13 00:38:57 +01:00
|
|
|
/* and do not move till end */
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_SEARCH_STRUCT *dir; /* for dir searches */
|
2011-11-13 00:38:56 +01:00
|
|
|
N_NW_PATH nwpath;
|
|
|
|
} DIR_BASE_ENTRY;
|
|
|
|
|
|
|
|
static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES];
|
|
|
|
static int anz_dbe = 0;
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static void init_nwpath(N_NW_PATH *nwpath, int namespace)
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
|
|
|
nwpath->volume = -1;
|
2011-11-13 00:38:57 +01:00
|
|
|
nwpath->namespace = namespace;
|
2011-11-13 00:38:56 +01:00
|
|
|
nwpath->has_wild = 0;
|
|
|
|
nwpath->fn = nwpath->path;
|
|
|
|
*(nwpath->path) = '\0';
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static void norm_nwpath_fn(N_NW_PATH *nwpath)
|
|
|
|
{
|
|
|
|
nwpath->fn = (uint8*)strrchr((char*)nwpath->path, '/');
|
|
|
|
if (nwpath->fn) nwpath->fn++;
|
|
|
|
else nwpath->fn=nwpath->path;
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus,
|
2011-11-13 00:38:56 +01:00
|
|
|
int allocate_extra, uint8 *extra_path)
|
2011-11-13 00:38:56 +01:00
|
|
|
/*
|
|
|
|
* returns complete UNIX path
|
|
|
|
* modus & 1 : ignore fn, (only path)
|
|
|
|
* modus & 2 : no '/' at end
|
|
|
|
*
|
2011-11-13 00:38:56 +01:00
|
|
|
* if allocate_extra > 0, then the returned buffer must be
|
|
|
|
* deallocated later
|
2011-11-13 00:38:56 +01:00
|
|
|
*/
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
static char *last_unixname=NULL;
|
|
|
|
char *unixname;
|
2011-11-13 00:38:56 +01:00
|
|
|
int len;
|
2011-11-13 00:38:56 +01:00
|
|
|
int volume = nwpath->volume;
|
|
|
|
int len_extra = (extra_path) ? strlen(extra_path) : 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
char *p, *pp;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (volume < 0 || volume >= used_nw_volumes || !nw_volumes[volume].unixnamlen ) {
|
|
|
|
char *errorstr="Z/Z/Z";
|
|
|
|
errorp(0, "xnwpath_2_unix", "volume=%d not ok", volume);
|
|
|
|
len = strlen(errorstr);
|
|
|
|
unixname=xmalloc(len_extra+allocate_extra+len+10);
|
|
|
|
strcpy(unixname, errorstr);
|
2011-11-13 00:38:56 +01:00
|
|
|
} else {
|
|
|
|
int m = ((modus & 1) && nwpath->fn > nwpath->path) /* last path = fn */
|
|
|
|
? nwpath->fn - nwpath->path
|
|
|
|
: strlen((char*)nwpath->path);
|
|
|
|
len = nw_volumes[volume].unixnamlen;
|
2011-11-13 00:38:56 +01:00
|
|
|
unixname=xmalloc(len_extra+allocate_extra+m+len+10);
|
|
|
|
memcpy(unixname, nw_volumes[volume].unixname, len);
|
|
|
|
/* first UNIXNAME VOLUME */
|
|
|
|
p = pp = unixname+len;
|
|
|
|
memcpy(p, nwpath->path, m); /* path or partiell path */
|
|
|
|
len += m;
|
|
|
|
p += m;
|
|
|
|
if ((modus & 2) && *(p-1) == '/' ) {
|
|
|
|
if (p > unixname+1) {
|
|
|
|
--p;
|
|
|
|
--len;
|
|
|
|
} else {
|
|
|
|
*p++ = '.';
|
|
|
|
++len;
|
|
|
|
}
|
|
|
|
} else if (len_extra) {
|
|
|
|
if (*(p-1) != '/') {
|
|
|
|
*p++='/';
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
memcpy(p, extra_path, len_extra);
|
|
|
|
p += len_extra;
|
|
|
|
len += len_extra;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
*p = '\0';
|
2011-11-13 00:38:57 +01:00
|
|
|
if (nwpath->namespace == NAME_DOS
|
|
|
|
&& nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT)
|
2011-11-13 00:38:56 +01:00
|
|
|
downstr((uint8*)pp);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
if (!allocate_extra) {
|
|
|
|
xfree(last_unixname);
|
|
|
|
last_unixname=unixname;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(unixname);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
#define nwpath_2_unix(nwpath, modus) \
|
|
|
|
xnwpath_2_unix((nwpath), (modus), 0, NULL)
|
|
|
|
#define nwpath_2_unix1(nwpath, modus, extrabytes) \
|
|
|
|
xnwpath_2_unix((nwpath), (modus), (extrabytes), NULL)
|
|
|
|
#define nwpath_2_unix2(nwpath, modus, extrabytes, extrastr) \
|
|
|
|
xnwpath_2_unix((nwpath), (modus), (extrabytes), extrastr)
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
static void free_dbe_dir(DIR_BASE_ENTRY *dbe)
|
|
|
|
{
|
|
|
|
DIR_SEARCH_STRUCT *d = dbe->dir;
|
|
|
|
if (NULL != d) {
|
|
|
|
if (d->fdir) closedir(d->fdir);
|
|
|
|
xfree(d->unixname);
|
|
|
|
xfree(dbe->dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int allocate_dbe_dir(DIR_BASE_ENTRY *dbe)
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_SEARCH_STRUCT *d=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT));
|
2011-11-13 00:38:56 +01:00
|
|
|
if (dbe->dir) free_dbe_dir(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
dbe->dir = d;
|
|
|
|
d->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258);
|
|
|
|
XDPRINTF((4, 0, "UNIXNAME='%s'", d->unixname));
|
|
|
|
d->fdir = opendir(d->unixname);
|
|
|
|
if (NULL == d->fdir) {
|
2011-11-13 00:38:56 +01:00
|
|
|
free_dbe_dir(dbe);
|
|
|
|
return(-0xff);
|
|
|
|
} else {
|
2011-11-13 00:38:56 +01:00
|
|
|
d->kpath = d->unixname+strlen(d->unixname);
|
|
|
|
*(d->kpath) = '/';
|
|
|
|
*(++(d->kpath)) = '\0';
|
2011-11-13 00:38:56 +01:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_dbe_ptr(DIR_BASE_ENTRY *dbe)
|
|
|
|
{
|
|
|
|
if (dbe != (DIR_BASE_ENTRY*)NULL) {
|
|
|
|
free_dbe_dir(dbe);
|
|
|
|
xfree(dbe);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int base_open_seek_dir(DIR_BASE_ENTRY *dbe, uint32 offset)
|
2011-11-13 00:38:57 +01:00
|
|
|
/* opens a directory struct for searching */
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
int result = S_ISDIR(dbe->nwpath.statb.st_mode) ? 0 : -0xff;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (!result) {
|
2011-11-13 00:38:56 +01:00
|
|
|
if (offset == MAX_U32) {
|
|
|
|
free_dbe_dir(dbe);
|
|
|
|
offset = 0L;
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL == dbe->dir) result=allocate_dbe_dir(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (result > -1) seekdir(dbe->dir->fdir, offset);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (result < 0 && NULL != dbe->dir) free_dbe_dir(dbe);
|
|
|
|
XDPRINTF((3, 0, "base_open_seek_dir offset=%d, result=%d", offset, result));
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static DIR_BASE_ENTRY *allocate_dbe_p(int namespace)
|
2011-11-13 00:38:56 +01:00
|
|
|
/* returns new allocated dir_base_entry */
|
|
|
|
{
|
|
|
|
int j=-1;
|
2011-11-13 00:38:56 +01:00
|
|
|
int to_use=-1;
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY **pdbe=(DIR_BASE_ENTRY**) NULL;
|
2011-11-13 00:38:57 +01:00
|
|
|
|
|
|
|
/* if (namespace) return(NULL); /* TODO: more namespaces */
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
while (++j < anz_dbe && NULL != *(pdbe = &(dir_base[j])) ){
|
|
|
|
if (to_use < 0 && !(*pdbe)->basehandle && !(*pdbe)->locked) to_use=j;
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
if (j == anz_dbe) {
|
|
|
|
if (anz_dbe == MAX_DIR_BASE_ENTRIES) { /* return(-0xff); */
|
2011-11-13 00:38:56 +01:00
|
|
|
if (to_use > -1) j=to_use;
|
|
|
|
else while (j--) {
|
|
|
|
pdbe = &(dir_base[j]);
|
|
|
|
if (!(*pdbe)->locked) break; /* remove last not locked from list */
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
free_dbe_ptr(*pdbe);
|
|
|
|
} else pdbe = &(dir_base[anz_dbe++]);
|
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
*pdbe = (DIR_BASE_ENTRY*)xcmalloc(sizeof(DIR_BASE_ENTRY));
|
2011-11-13 00:38:56 +01:00
|
|
|
(*pdbe)->slot = j;
|
2011-11-13 00:38:57 +01:00
|
|
|
init_nwpath(&((*pdbe)->nwpath), namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
return(*pdbe);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe)
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe && NULL != *dbe) {
|
|
|
|
int slot = (*dbe)->slot;
|
|
|
|
free_dbe_ptr(*dbe);
|
|
|
|
dir_base[slot] = *dbe = (DIR_BASE_ENTRY*)NULL;
|
|
|
|
if (slot+1 == anz_dbe) {
|
2011-11-13 00:38:56 +01:00
|
|
|
while (anz_dbe && ((DIR_BASE_ENTRY*)NULL == dir_base[anz_dbe-1]) )
|
|
|
|
--anz_dbe;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
#define free_dbe_p(dbe) xx_free_dbe_p(&(dbe))
|
2011-11-13 00:38:56 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
#define free_dbe(dbase) \
|
|
|
|
xx_free_dbe_p(((dbase) > -1 && (dbase) < anz_dbe) ? &(dir_base[dbase]) : NULL)
|
|
|
|
|
|
|
|
static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe)
|
2011-11-13 00:38:56 +01:00
|
|
|
/* routine touchs this entry and returns the new offset */
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
int dbase = (NULL != dbe) ? dbe->slot : -1;
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((4, 0, "touch_handle_entry entry dbase=%d", dbase));
|
|
|
|
if (dbase > 2) {
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY **dbp=&(dir_base[dbase]);
|
2011-11-13 00:38:57 +01:00
|
|
|
DIR_BASE_ENTRY **dbpq=dbp;
|
|
|
|
int aktbase=dbase;
|
2011-11-13 00:38:56 +01:00
|
|
|
while (dbase--) {
|
2011-11-13 00:38:57 +01:00
|
|
|
--dbpq;
|
|
|
|
if ( dbase < (MAX_DIR_BASE_ENTRIES/2) || !(*dbpq) || !(*dbpq)->locked) {
|
|
|
|
*dbp = *dbpq;
|
|
|
|
if (*dbp) (*dbp)->slot = dbase+1;
|
|
|
|
dbp=dbpq;
|
|
|
|
aktbase=dbase;
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
dbase = aktbase;
|
|
|
|
dir_base[dbase] = dbe;
|
|
|
|
dbe->slot = dbase;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
XDPRINTF((4, 0, "touch_handle_entry return dbase=%d", dbase));
|
|
|
|
return(dbase);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
#define touch_handle_entry(dbase) \
|
|
|
|
touch_handle_entry_p(((dbase) > -1 && (dbase) < anz_dbe) ? dir_base[dbase] : NULL)
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
char *debug_nwpath_name(N_NW_PATH *p)
|
2011-11-13 00:38:56 +01:00
|
|
|
/* only for debugging */
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
#if DO_DEBUG
|
2011-11-13 00:38:56 +01:00
|
|
|
static char *nwpathname=NULL;
|
2011-11-13 00:38:56 +01:00
|
|
|
char volname[300];
|
2011-11-13 00:38:56 +01:00
|
|
|
int len;
|
|
|
|
if (nw_get_volume_name(p->volume, volname) < 1)
|
2011-11-13 00:38:56 +01:00
|
|
|
sprintf(volname, "<%d=NOT-OK>", (int)p->volume);
|
2011-11-13 00:38:56 +01:00
|
|
|
len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 30;
|
|
|
|
xfree(nwpathname);
|
|
|
|
nwpathname=xmalloc(len);
|
2011-11-13 00:38:56 +01:00
|
|
|
sprintf(nwpathname, "`%s:%s`,fn=`%s`", volname, p->path, p->fn);
|
|
|
|
#else
|
|
|
|
static char nwpathname[2];
|
|
|
|
nwpathname[0]='\0';
|
|
|
|
nwpathname[1]='\0';
|
|
|
|
#endif
|
|
|
|
return(nwpathname);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes)
|
2011-11-13 00:38:56 +01:00
|
|
|
/* returns size of path components in bytes */
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
|
|
|
int k = -1;
|
|
|
|
int size = 0;
|
|
|
|
while (++k < nwp->components) {
|
|
|
|
int len = (int) *(pp_pathes++);
|
|
|
|
pp_pathes+= len;
|
|
|
|
size += len;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
return(size);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
static int add_hpath_to_nwpath(N_NW_PATH *nwpath,
|
|
|
|
NW_HPATH *nwp, uint8 *pp_pathes)
|
|
|
|
/* Routine adds nwp to nwpath */
|
|
|
|
/* nwpath must be setup correctly before entry */
|
|
|
|
/* return > -1 if ok */
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
int k = -1;
|
|
|
|
uint8 *pp = nwpath->path+strlen(nwpath->path);
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((2, 0, "entry add_hpath_to_nwpath: %s",
|
|
|
|
debug_nwpath_name(nwpath)));
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
while (!result && ++k < nwp->components) {
|
|
|
|
int len = (int) *(pp_pathes++);
|
|
|
|
uint8 *p = pp_pathes;
|
|
|
|
pp_pathes+=len;
|
|
|
|
|
|
|
|
if (!k && nwpath->volume == -1) { /* first component is volume */
|
|
|
|
if ((nwpath->volume=nw_get_volume_number(p, len)) < 0) {
|
|
|
|
result = nwpath->volume;
|
|
|
|
goto leave_build_nwpath;
|
|
|
|
}
|
|
|
|
} else { /* here is path (+ fn ) */
|
|
|
|
int i=len;
|
|
|
|
if (pp > nwpath->path) { /* not the first entry */
|
2011-11-13 00:38:57 +01:00
|
|
|
*pp = '/';
|
|
|
|
*++pp = '\0';
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
while (i--) {
|
|
|
|
if (*p == 0xae) *pp++ = '.';
|
2011-11-13 00:38:57 +01:00
|
|
|
else if (*p > 0x60 && *p < 0x7b && nwpath->namespace == NAME_DOS) {
|
2011-11-13 00:38:56 +01:00
|
|
|
*pp++ = *p - 0x20; /* all is upshift */
|
|
|
|
} else if (*p == 0xaa || *p == '*' ) {
|
|
|
|
*pp++ = '*';
|
|
|
|
nwpath->has_wild++;
|
|
|
|
} else if (*p == 0xbf || *p == '?' ) {
|
|
|
|
*pp++ = '?';
|
|
|
|
nwpath->has_wild++;
|
|
|
|
} else if (*p == '/' || *p == '\\') {
|
|
|
|
*pp++ = '/';
|
|
|
|
} else if (*p == ':') { /* extract volume */
|
|
|
|
int vlen = (int) (pp - nwpath->path);
|
|
|
|
if ((nwpath->volume=nw_get_volume_number(nwpath->path, vlen)) < 0) {
|
|
|
|
result = nwpath->volume;
|
|
|
|
goto leave_build_nwpath;
|
|
|
|
}
|
|
|
|
pp=nwpath->path;
|
|
|
|
*pp='\0';
|
|
|
|
} else *pp++ = *p;
|
|
|
|
p++;
|
|
|
|
} /* while */
|
|
|
|
*pp = '\0';
|
|
|
|
} /* else */
|
|
|
|
} /* while */
|
|
|
|
if (nwpath->volume < 0) result=-0x9c;
|
|
|
|
leave_build_nwpath:
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((2, 0, "add_hpath_to_nwpath: result=0x%x, %s",
|
2011-11-13 00:38:56 +01:00
|
|
|
result, debug_nwpath_name(nwpath)));
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static int nwp_stat(N_NW_PATH *nwpath, char *debstr)
|
|
|
|
{
|
|
|
|
uint8 *uname=nwpath_2_unix1(nwpath, 2, 1);
|
|
|
|
int result=stat(uname, &(nwpath->statb));
|
|
|
|
if (nw_debug) {
|
|
|
|
char xdebstr[2];
|
|
|
|
if (!debstr) {
|
|
|
|
xdebstr[0]='\0';
|
|
|
|
debstr = xdebstr;
|
|
|
|
}
|
|
|
|
XDPRINTF((4, 0, "nwp_stat:%s:%d,`%s`",
|
|
|
|
debstr,
|
|
|
|
result,
|
|
|
|
debug_nwpath_name(nwpath)));
|
|
|
|
}
|
|
|
|
xfree(uname);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static uint32 name_2_base(N_NW_PATH *nwpath, int namespace, int no_stat)
|
2011-11-13 00:38:56 +01:00
|
|
|
/* returns basehandle of path, or 0 if not exist !! */
|
|
|
|
/* nwpath must be filled, namespace must be specified */
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
|
|
|
uint32 basehandle=0L;
|
2011-11-13 00:38:57 +01:00
|
|
|
if (no_stat || !nwp_stat(nwpath, "name_2_base")) {
|
2011-11-13 00:38:56 +01:00
|
|
|
DEV_NAMESPACE_MAP dnm;
|
|
|
|
dnm.dev = nwpath->statb.st_dev;
|
|
|
|
dnm.namespace = namespace;
|
2011-11-13 00:38:56 +01:00
|
|
|
basehandle = nw_vol_inode_to_handle(nwpath->volume,
|
2011-11-13 00:38:56 +01:00
|
|
|
nwpath->statb.st_ino,
|
|
|
|
&dnm);
|
|
|
|
}
|
|
|
|
return(basehandle);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int add_dbe_entry(int namspace, int volume,
|
|
|
|
uint32 basehandle, uint8 *path)
|
|
|
|
{
|
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(namspace);
|
|
|
|
if (dbe) {
|
|
|
|
dbe->nwpath.volume = volume;
|
|
|
|
dbe->basehandle = basehandle;
|
|
|
|
if (path) {
|
|
|
|
strcpy(dbe->nwpath.path, path);
|
|
|
|
norm_nwpath_fn(&(dbe->nwpath));
|
|
|
|
}
|
|
|
|
return(touch_handle_entry_p(dbe));
|
|
|
|
} else return(-0x9b);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static int find_base_entry(int volume, uint32 basehandle)
|
|
|
|
{
|
|
|
|
int k=-1;
|
2011-11-13 00:38:57 +01:00
|
|
|
DEV_NAMESPACE_MAP dnm;
|
|
|
|
ino_t ino = nw_vol_handle_to_inode(volume, basehandle, &dnm);
|
2011-11-13 00:38:56 +01:00
|
|
|
while (++k < anz_dbe) {
|
|
|
|
DIR_BASE_ENTRY *e=dir_base[k];
|
|
|
|
if ( (DIR_BASE_ENTRY*)NULL != e
|
2011-11-13 00:38:57 +01:00
|
|
|
&& volume == e->nwpath.volume
|
|
|
|
&& ( (basehandle == e->basehandle)
|
|
|
|
|| (ino == e->nwpath.statb.st_ino)) )
|
|
|
|
return(k);
|
|
|
|
}
|
|
|
|
/* now we test whether it is the root of volume */
|
|
|
|
if (0 < (ino = nw_vol_handle_to_inode(volume, basehandle, &dnm))
|
|
|
|
&& ino == get_volume_inode(volume) ) {
|
|
|
|
/* its the handle of the volumes root */
|
|
|
|
return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(-0x9b);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static int insert_get_base_entry(DIR_BASE_ENTRY *dbe,
|
2011-11-13 00:38:56 +01:00
|
|
|
int namespace, int creatmode)
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
N_NW_PATH *nwpath = &(dbe->nwpath);
|
2011-11-13 00:38:57 +01:00
|
|
|
uint32 basehandle = name_2_base(nwpath, namespace, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
if (!basehandle && creatmode) { /* now creat the entry (file or dir) */
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = 0;
|
|
|
|
char *unname = nwpath_2_unix(nwpath, 2);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (get_volume_options(nwpath->volume, 1) &
|
|
|
|
VOL_OPTION_READONLY) return(-0x8a);
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
if (creatmode & FILE_ATTR_DIR) {
|
|
|
|
/* creat dir */
|
|
|
|
if (mkdir(unname, 0777)) result=-0x84;
|
|
|
|
} else {
|
|
|
|
/* creat file */
|
|
|
|
if ((result = creat(unname, 0777)) > -1) {
|
|
|
|
close(result);
|
|
|
|
result = 0;
|
|
|
|
} else result=-0x84;
|
|
|
|
}
|
|
|
|
if (result) return(result);
|
2011-11-13 00:38:57 +01:00
|
|
|
basehandle = name_2_base(nwpath, namespace, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
if (basehandle) {
|
|
|
|
int k=-1;
|
|
|
|
while (++k < anz_dbe) {
|
|
|
|
DIR_BASE_ENTRY *e=dir_base[k];
|
|
|
|
if ( (DIR_BASE_ENTRY*)NULL != e
|
2011-11-13 00:38:56 +01:00
|
|
|
&& basehandle == e->basehandle
|
2011-11-13 00:38:56 +01:00
|
|
|
&& nwpath->volume == e->nwpath.volume) {
|
2011-11-13 00:38:56 +01:00
|
|
|
free_dbe_p(e);
|
|
|
|
dbe->basehandle = basehandle;
|
|
|
|
return(touch_handle_entry_p(dbe));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
} /* while */
|
|
|
|
/* now i know that it's a new base entry */
|
|
|
|
dbe->basehandle = basehandle;
|
2011-11-13 00:38:56 +01:00
|
|
|
return(touch_handle_entry_p(dbe));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
return(-0xff); /* invalid path = -0x9c, -0xff no matching files */
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int build_base(int namespace,
|
|
|
|
NW_HPATH *nwp,
|
|
|
|
uint8 *pathes,
|
|
|
|
DIR_BASE_ENTRY *dbe,
|
|
|
|
int mode,
|
|
|
|
uint8 *rets)
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
/* routine returns the actual dbe entry offset or */
|
|
|
|
/* < 0 if error */
|
2011-11-13 00:38:57 +01:00
|
|
|
/* if mode == 1, then last path element will be ignored and will be put */
|
2011-11-13 00:38:56 +01:00
|
|
|
/* into the rets variable */
|
|
|
|
{
|
|
|
|
N_NW_PATH *nwpath=&(dbe->nwpath);
|
|
|
|
int result=0;
|
|
|
|
if (!nwp->flag) { /* short handle */
|
2011-11-13 00:38:57 +01:00
|
|
|
int dir_handle = (int)nwp->base[0];
|
|
|
|
NW_DIR *dir = (dir_handle > 0 && dir_handle <= used_dirs)
|
|
|
|
? &(dirs[dir_handle-1])
|
|
|
|
: NULL;
|
|
|
|
if (dir && dir->inode) {
|
|
|
|
int llen = strlen(dir->path);
|
|
|
|
nwpath->volume = dir->volume;
|
|
|
|
memcpy(nwpath->path, dir->path, llen+1);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (llen && *(nwpath->path + llen -1) == '/')
|
|
|
|
*(nwpath->path+llen-1) = '\0';
|
2011-11-13 00:38:56 +01:00
|
|
|
result = (nwpath->volume > -1) ? 0 : -0x98;
|
|
|
|
} else result = -0x9b;
|
2011-11-13 00:38:57 +01:00
|
|
|
XDPRINTF((4, 0, "build_base with dir_handle=%d, result=x%x",
|
|
|
|
dir_handle, result));
|
2011-11-13 00:38:56 +01:00
|
|
|
} else if (nwp->flag == 1) { /* basehandle */
|
2011-11-13 00:38:57 +01:00
|
|
|
if (-1 < (result = find_base_entry(nwp->volume, GET_32(nwp->base)))) {
|
|
|
|
DIR_BASE_ENTRY *e=dir_base[result];
|
|
|
|
nwpath->volume = nwp->volume;
|
|
|
|
strcpy(nwpath->path, e->nwpath.path);
|
|
|
|
result = 0;
|
|
|
|
} else if (!GET_32(nwp->base)) {
|
|
|
|
nwpath->volume = nwp->volume;
|
|
|
|
nwpath->path[0]='\0';
|
|
|
|
result = 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:57 +01:00
|
|
|
XDPRINTF((4, 0, "build_base with basehandle=%ld, result=x%x",
|
|
|
|
GET_32(nwp->base), result));
|
2011-11-13 00:38:56 +01:00
|
|
|
} else if (nwp->flag != 0xff) result=-0xff;
|
|
|
|
if (!result) {
|
2011-11-13 00:38:57 +01:00
|
|
|
nwpath->namespace = namespace;
|
2011-11-13 00:38:56 +01:00
|
|
|
if ((result = add_hpath_to_nwpath(nwpath, nwp, pathes)) > -1) {
|
|
|
|
char *pp=strrchr((char*)nwpath->path, '/');
|
|
|
|
if (mode) {
|
|
|
|
if (pp) {
|
|
|
|
if (rets) strcpy(rets, pp+1);
|
|
|
|
*(pp)=0;
|
|
|
|
pp=strrchr((char*)nwpath->path, '/');
|
|
|
|
} else {
|
|
|
|
if (rets) strcpy(rets, nwpath->path);
|
|
|
|
*(nwpath->path) = '\0';
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
nwpath->fn = (pp) ? (uint8*)pp+1 : nwpath->path;
|
2011-11-13 00:38:57 +01:00
|
|
|
result = insert_get_base_entry(dbe, namespace, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
int nw_generate_dir_path(int namespace,
|
|
|
|
NW_HPATH *nwp,
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 *ns_dir_base,
|
|
|
|
uint8 *dos_dir_base)
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
/* returns Volume Number >=0 or errcode < 0 if error */
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = -0xfb;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
U32_TO_32(dbe->basehandle, ns_dir_base); /* LOW - HIGH */
|
2011-11-13 00:38:57 +01:00
|
|
|
if (namespace != NAME_DOS) {
|
|
|
|
U32_TO_32(name_2_base(&(dbe->nwpath), NAME_DOS, 1), dos_dir_base);
|
|
|
|
} else {
|
|
|
|
U32_TO_32(dbe->basehandle, dos_dir_base);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "nw_generate_dir_path path=%s, result=%d, basehandle=0x%x",
|
|
|
|
debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle));
|
|
|
|
result= dbe->nwpath.volume;
|
2011-11-13 00:38:56 +01:00
|
|
|
} else free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (result < 0) {
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "nw_generate_dir_path NOT OK result=-0x%x", -result));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
|
|
|
|
{
|
|
|
|
N_NW_PATH *nwpath=&(dbe->nwpath);
|
|
|
|
struct stat *stb=&(nwpath->statb);
|
|
|
|
int result = 76;
|
|
|
|
memset(p, 0, result);
|
|
|
|
if (infomask & INFO_MSK_DATA_STREAM_SPACE) {
|
|
|
|
U32_TO_32(stb->st_size, p);
|
|
|
|
}
|
|
|
|
p += 4;
|
|
|
|
if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
|
|
|
|
uint32 mask=0L;
|
|
|
|
if (S_ISDIR(stb->st_mode)) mask |= FILE_ATTR_DIR;
|
|
|
|
U32_TO_32(mask, p);
|
|
|
|
p += 4;
|
|
|
|
U16_TO_16((uint16)(mask & 0xFFFF), p);
|
|
|
|
p +=2;
|
|
|
|
} else p+=6;
|
|
|
|
if (infomask & INFO_MSK_DATA_STREAM_SIZE) {
|
|
|
|
U32_TO_32(stb->st_size, p);
|
|
|
|
}
|
|
|
|
p +=4;
|
|
|
|
if (infomask & INFO_MSK_TOTAL_DATA_STREAM_SIZE) {
|
|
|
|
U32_TO_32(stb->st_size, p);
|
|
|
|
p +=4;
|
|
|
|
U16_TO_16(0, p);
|
|
|
|
p +=2;
|
|
|
|
} else p+=6;
|
|
|
|
if (infomask & INFO_MSK_CREAT_INFO) {
|
2011-11-13 00:38:57 +01:00
|
|
|
un_time_2_nw(stb->st_mtime, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
2011-11-13 00:38:57 +01:00
|
|
|
un_date_2_nw(stb->st_mtime, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
|
|
|
U32_TO_32(1, p);
|
|
|
|
p +=4;
|
|
|
|
} else p+=8;
|
|
|
|
if (infomask & INFO_MSK_MODIFY_INFO) {
|
2011-11-13 00:38:57 +01:00
|
|
|
un_time_2_nw(stb->st_mtime, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
2011-11-13 00:38:57 +01:00
|
|
|
un_date_2_nw(stb->st_mtime, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
|
|
|
U32_TO_32(1, p);
|
|
|
|
p +=4;
|
2011-11-13 00:38:57 +01:00
|
|
|
un_date_2_nw(stb->st_atime, p, 0); /* access date */
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
|
|
|
} else p+=10;
|
|
|
|
if (infomask & INFO_MSK_ARCHIVE_INFO) {
|
2011-11-13 00:38:57 +01:00
|
|
|
un_time_2_nw(0, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
2011-11-13 00:38:57 +01:00
|
|
|
un_date_2_nw(0, p, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
p +=2;
|
|
|
|
U32_TO_32(0, p);
|
|
|
|
p +=4;
|
|
|
|
} else p+=8;
|
|
|
|
if (infomask & INFO_MSK_RIGHTS_INFO) {
|
|
|
|
U16_TO_16(0, p);
|
|
|
|
}
|
|
|
|
p +=2;
|
|
|
|
if (infomask & INFO_MSK_DIR_ENTRY_INFO) {
|
|
|
|
U32_TO_32(dbe->basehandle, p);
|
|
|
|
p +=4;
|
|
|
|
U32_TO_32(dbe->basehandle, p);
|
|
|
|
p +=4;
|
|
|
|
U32_TO_32(nwpath->volume, p);
|
|
|
|
p +=4;
|
|
|
|
} else p+=12;
|
|
|
|
if (infomask & INFO_MSK_EXT_ATTRIBUTES) {
|
|
|
|
U32_TO_32(0, p); /* Ext Attr Data Size */
|
|
|
|
p +=4;
|
|
|
|
U32_TO_32(0, p); /* Ext Attr Count */
|
|
|
|
p +=4;
|
|
|
|
U32_TO_32(0, p); /* Ext Attr Key Size */
|
|
|
|
p +=4;
|
|
|
|
} else p+=12;
|
|
|
|
if (infomask & INFO_MSK_NAME_SPACE_INFO){
|
|
|
|
U32_TO_32(0, p); /* Creator of the name space number */
|
|
|
|
}
|
|
|
|
p +=4;
|
|
|
|
/* ---------------------------------------------- */
|
|
|
|
if (infomask & INFO_MSK_ENTRY_NAME) {
|
|
|
|
*p = (uint8) strlen(nwpath->fn);
|
|
|
|
result++;
|
|
|
|
if (*p) {
|
|
|
|
memcpy(p+1, nwpath->fn, (int) *p);
|
|
|
|
result += (int) *p;
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "build_dir_info:path=%s, result=%d, basehandle=0x%x, mask=0x%lx",
|
|
|
|
debug_nwpath_name(nwpath), result, dbe->basehandle, infomask));
|
2011-11-13 00:38:56 +01:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp,
|
|
|
|
int destnamspace,
|
|
|
|
int searchattrib, uint32 infomask,
|
|
|
|
uint8 *responsedata)
|
|
|
|
/* returns sizeof info_mask
|
|
|
|
* the sizeof info_mask is NOT related by the infomask.
|
|
|
|
* But the _valid_ info is.
|
|
|
|
*/
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = -0xfb;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info");
|
|
|
|
result = build_dir_info(dbe, infomask, responsedata);
|
2011-11-13 00:38:56 +01:00
|
|
|
} else free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (result < 0) {
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", -result));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int nw_init_search(int namespace,
|
2011-11-13 00:38:56 +01:00
|
|
|
NW_HPATH *nwp,
|
2011-11-13 00:38:57 +01:00
|
|
|
uint8 *pathes,
|
|
|
|
uint8 *responsedata)
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = -0xfb;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
result = base_open_seek_dir(dbe, 0L);
|
|
|
|
if (result > -1) {
|
|
|
|
*responsedata++ = dbe->nwpath.volume;
|
|
|
|
U32_TO_32(dbe->basehandle, responsedata);
|
|
|
|
responsedata+=4;
|
|
|
|
U32_TO_32(0L, responsedata); /* searchsequenz */
|
|
|
|
result = 9;
|
|
|
|
}
|
|
|
|
XDPRINTF((3, 0, "nw_init_search path=%s, result=%d, basehandle=0x%x",
|
|
|
|
debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle));
|
2011-11-13 00:38:56 +01:00
|
|
|
} else free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (result < 0) {
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "nw_init_search NOT OK result=%d", result));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
int get_add_new_entry(DIR_BASE_ENTRY *qbe, uint8 *path, int creatmode)
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(qbe->nwpath.namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:56 +01:00
|
|
|
N_NW_PATH *nwpath=&(dbe->nwpath);
|
|
|
|
int result = -0x9c;
|
2011-11-13 00:38:56 +01:00
|
|
|
nwpath->volume = qbe->nwpath.volume;
|
2011-11-13 00:38:56 +01:00
|
|
|
strcpy(nwpath->path, qbe->nwpath.path);
|
|
|
|
nwpath->fn = nwpath->path+strlen(nwpath->path);
|
|
|
|
if (nwpath->fn > nwpath->path && *(nwpath->fn-1) != '/') {
|
|
|
|
*(nwpath->fn) = '/';
|
2011-11-13 00:38:56 +01:00
|
|
|
*(++nwpath->fn) = '\0';
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
strcpy(nwpath->fn, path);
|
2011-11-13 00:38:57 +01:00
|
|
|
result = insert_get_base_entry(dbe, qbe->nwpath.namespace, creatmode);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (result < 0) free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
return(result);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
return(-1);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:57 +01:00
|
|
|
static int namespace_fn_match(uint8 *s, uint8 *p, int namespace)
|
|
|
|
/* for other namespaces than DOS */
|
|
|
|
{
|
|
|
|
int pc, sc;
|
|
|
|
uint state = 0;
|
|
|
|
int anf, ende;
|
|
|
|
int not = 0;
|
|
|
|
uint found = 0;
|
|
|
|
while ( (pc = *p++) != 0) {
|
|
|
|
switch (state){
|
|
|
|
case 0 :
|
|
|
|
if (pc == 255) {
|
|
|
|
switch (pc=*p++) {
|
|
|
|
case 0xaa :
|
|
|
|
case '*' : pc=3000; break; /* star */
|
|
|
|
|
|
|
|
case 0xae :
|
|
|
|
case '.' : pc=1000; break; /* point */
|
|
|
|
|
|
|
|
case 0xbf :
|
|
|
|
case '?' : pc=2000; break; /* ? */
|
|
|
|
|
|
|
|
default : pc=*(--p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (pc == '\\') continue;
|
|
|
|
|
|
|
|
switch (pc) {
|
|
|
|
case 1000: if ('.' != *s++) return(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2000: if (!*s++) return(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3000 : if (!*p) return(1);
|
|
|
|
while (*s){
|
|
|
|
if (namespace_fn_match(s, p, namespace) == 1) return(1);
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
case '[' : if ( (*p == '!') || (*p == '^') ){
|
|
|
|
++p;
|
|
|
|
not = 1;
|
|
|
|
}
|
|
|
|
state = 1;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
default : if ( pc != *s &&
|
|
|
|
( namespace != NAME_OS2
|
|
|
|
|| (!isalpha(pc)) || (!isalpha(*s))
|
|
|
|
|| (pc | 0x20) != (*s | 0x20) ) )
|
|
|
|
return(0);
|
|
|
|
++s;
|
|
|
|
break;
|
|
|
|
|
|
|
|
} /* switch */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1 : /* Bereich von Zeichen */
|
|
|
|
sc = *s++;
|
|
|
|
found = not;
|
|
|
|
if (!sc) return(0);
|
|
|
|
do {
|
|
|
|
if (pc == '\\') pc = *(p++);
|
|
|
|
if (!pc) return(0);
|
|
|
|
anf = pc;
|
|
|
|
if (*p == '-' && *(p+1) != ']'){
|
|
|
|
ende = *(++p);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
else ende = anf;
|
|
|
|
if (found == not) { /* only if not found */
|
|
|
|
if (anf == sc || (anf <= sc && sc <= ende))
|
|
|
|
found = !not;
|
|
|
|
}
|
|
|
|
} while ((pc = *(p++)) != ']');
|
|
|
|
if (! found ) return(0);
|
|
|
|
not = 0;
|
|
|
|
found = 0;
|
|
|
|
state = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default : break;
|
|
|
|
} /* switch */
|
|
|
|
} /* while */
|
|
|
|
return ( (*s) ? 0 : 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
int nw_search_file_dir(int namespace, int datastream,
|
|
|
|
uint32 searchattrib, uint32 infomask,
|
|
|
|
int volume, uint32 basehandle, uint32 sequence,
|
|
|
|
int len, uint8 *path, uint8 *responsedata)
|
|
|
|
|
|
|
|
{
|
|
|
|
int result = find_base_entry(volume, basehandle);
|
|
|
|
if (result > -1) {
|
|
|
|
DIR_BASE_ENTRY *dbe=dir_base[result];
|
|
|
|
if ((result = base_open_seek_dir(dbe, sequence)) > -1) {
|
|
|
|
uint8 entry[256];
|
|
|
|
struct dirent *dirbuff;
|
|
|
|
struct stat statb;
|
|
|
|
int dest_entry=-1;
|
|
|
|
DIR_SEARCH_STRUCT *ds=dbe->dir;
|
|
|
|
int vol_options = get_volume_options(volume, 0);
|
2011-11-13 00:38:56 +01:00
|
|
|
dbe->locked++;
|
2011-11-13 00:38:56 +01:00
|
|
|
strmaxcpy(entry, path, min(255, len));
|
2011-11-13 00:38:57 +01:00
|
|
|
if (namespace == NAME_DOS && (vol_options & VOL_OPTION_DOWNSHIFT))
|
|
|
|
downstr(entry);
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((5,0,"nw_search_file_dir searchpath=%s", entry));
|
|
|
|
while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){
|
|
|
|
if (dirbuff->d_ino) {
|
|
|
|
uint8 *name=(uint8*)(dirbuff->d_name);
|
|
|
|
XDPRINTF((10,0,"nw_search_file_dir Name=%s",
|
|
|
|
name));
|
|
|
|
if ( (name[0] != '.' && (
|
2011-11-13 00:38:57 +01:00
|
|
|
(!strcmp(name, entry))
|
|
|
|
|| (entry[0] == '*' && entry[1] == '\0' && namespace != NAME_DOS)
|
|
|
|
|| (namespace == NAME_DOS)
|
|
|
|
? fn_match(name, entry, vol_options)
|
|
|
|
: namespace_fn_match(name, entry, namespace) ))) {
|
2011-11-13 00:38:56 +01:00
|
|
|
strcpy(ds->kpath, name);
|
|
|
|
XDPRINTF((5,0,"nw_search_file_dir Name found=%s unixname=%s",
|
|
|
|
name, ds->unixname));
|
2011-11-13 00:38:56 +01:00
|
|
|
if (!stat(ds->unixname, &statb)) {
|
|
|
|
int flag= (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL;
|
|
|
|
if (!flag) {
|
|
|
|
if (S_ISDIR(statb.st_mode))
|
|
|
|
flag=(searchattrib & FILE_ATTR_DIR);
|
|
|
|
else
|
|
|
|
flag = !(searchattrib & FILE_ATTR_DIR);
|
|
|
|
}
|
|
|
|
if (flag) {
|
|
|
|
strcpy(entry, name);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (namespace == NAME_DOS &&
|
|
|
|
(vol_options & VOL_OPTION_DOWNSHIFT)) upstr(entry);
|
2011-11-13 00:38:56 +01:00
|
|
|
if ((dest_entry = get_add_new_entry(dbe, entry, 0)) > -1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
XDPRINTF((5,0,"nw_search_file_dir stat error"));
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* if */
|
|
|
|
} /* while */
|
|
|
|
*(ds->kpath) = '\0';
|
|
|
|
if (dest_entry > -1) {
|
|
|
|
DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry];
|
2011-11-13 00:38:56 +01:00
|
|
|
(void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir");
|
2011-11-13 00:38:56 +01:00
|
|
|
sequence = (uint32) telldir(ds->fdir);
|
|
|
|
*responsedata = (uint8) volume;
|
|
|
|
responsedata++;
|
|
|
|
U32_TO_32(basehandle, responsedata);
|
|
|
|
responsedata+=4;
|
|
|
|
U32_TO_32(sequence, responsedata);
|
|
|
|
responsedata+=4;
|
|
|
|
*responsedata = (uint8) 0; /* reserved */
|
|
|
|
responsedata++;
|
|
|
|
result = 10 +
|
|
|
|
build_dir_info(dest_dbe,
|
|
|
|
infomask|INFO_MSK_NAME_SPACE_INFO,
|
|
|
|
responsedata);
|
2011-11-13 00:38:56 +01:00
|
|
|
} else
|
|
|
|
result=-0xff; /* no files matching */
|
|
|
|
dbe->locked=0;
|
2011-11-13 00:38:56 +01:00
|
|
|
} /* if result */
|
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nw_open_creat_file_or_dir(int namespace,
|
|
|
|
int opencreatmode,
|
|
|
|
int attrib, uint32 infomask,
|
|
|
|
uint32 creatattrib,
|
|
|
|
int access_rights,
|
|
|
|
NW_HPATH *nwp, uint8 *pathes,
|
|
|
|
uint8 *responsedata)
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace);
|
2011-11-13 00:38:56 +01:00
|
|
|
int result = -0xfb;
|
2011-11-13 00:38:56 +01:00
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:56 +01:00
|
|
|
int exist=-1;
|
|
|
|
uint8 last_part[258];
|
|
|
|
*last_part='\0';
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
exist = result;
|
|
|
|
} else if (opencreatmode & OPC_MODE_CREAT) {
|
2011-11-13 00:38:57 +01:00
|
|
|
result = build_base(namespace, nwp, pathes, dbe, 1, last_part);
|
|
|
|
XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'",
|
|
|
|
result, last_part));
|
|
|
|
if (result > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
result = get_add_new_entry(dbe, last_part,
|
2011-11-13 00:38:56 +01:00
|
|
|
(creatattrib & FILE_ATTR_DIR) ? FILE_ATTR_DIR : 1);
|
2011-11-13 00:38:57 +01:00
|
|
|
if (result > -1)
|
|
|
|
dbe = dir_base[result];
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (result > -1) {
|
|
|
|
uint32 fhandle=0L;
|
|
|
|
int actionresult=0;
|
|
|
|
if (exist < 0) actionresult |= OPC_ACTION_CREAT;
|
|
|
|
if (!(creatattrib & FILE_ATTR_DIR)) {
|
|
|
|
int creatmode=0; /* open */
|
|
|
|
int attrib=0;
|
|
|
|
if (opencreatmode & (OPC_MODE_OPEN | OPC_MODE_CREAT) ) {
|
|
|
|
if (opencreatmode & OPC_MODE_CREAT) {
|
|
|
|
#if 0
|
|
|
|
if (exist > -1 && !(opencreatmode & OPC_MODE_REPLACE))
|
|
|
|
creatmode=2;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
creatmode = 1;
|
|
|
|
}
|
|
|
|
if ((result = file_creat_open(dbe->nwpath.volume,
|
|
|
|
nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb),
|
|
|
|
attrib, access_rights, creatmode)) > -1) {
|
|
|
|
fhandle = (uint32) result;
|
|
|
|
actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */
|
|
|
|
if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE))
|
|
|
|
actionresult |= OPC_ACTION_REPLACE; /* FILE REPLACED */
|
|
|
|
}
|
|
|
|
} else result=-0xff;
|
|
|
|
} else if (exist > -1) result=-0x84;
|
|
|
|
if (result > -1) {
|
|
|
|
U32_TO_BE32(fhandle, responsedata);
|
|
|
|
responsedata += 4;
|
|
|
|
*responsedata =(uint8) actionresult;
|
|
|
|
responsedata++ ;
|
|
|
|
result = 5 + build_dir_info(dbe,infomask, responsedata);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
} else free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
XDPRINTF((3, 0, "nw_open_creat mode=0x%x, creatattr=0x%x, access=0x%x, attr=0x%x, result=%d",
|
|
|
|
opencreatmode, creatattrib, access_rights, attrib, result));
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nw_delete_file_dir(int namespace, int searchattrib,
|
|
|
|
NW_HPATH *nwp)
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace);
|
|
|
|
int result = -0xfb;
|
|
|
|
if (dbe != NULL) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2);
|
2011-11-13 00:38:56 +01:00
|
|
|
if (get_volume_options(dbe->nwpath.volume, 1) &
|
|
|
|
VOL_OPTION_READONLY) result = -0x8a;
|
|
|
|
else {
|
|
|
|
if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
|
|
|
|
free_dbe_p(dbe);
|
|
|
|
result = rmdir(unname);
|
|
|
|
} else {
|
|
|
|
if (-1 < (result = unlink(unname)))
|
|
|
|
free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
if (result < 0) {
|
|
|
|
switch (errno) {
|
|
|
|
case EEXIST: result=-0xa0; /* dir not empty */
|
|
|
|
default: result=-0x8a; /* No privilegs */
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
result = 0;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
} else free_dbe_p(dbe);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
static int nw_alloc_short_dir_handle(int namespace, int hmode,
|
|
|
|
NW_HPATH *nwp, int task, int *volume)
|
|
|
|
{
|
|
|
|
DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace);
|
|
|
|
int result = -0xfb;
|
|
|
|
if (NULL != dbe) {
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwp, nwp->pathes, dbe, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
|
|
|
|
result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path,
|
|
|
|
dbe->nwpath.statb.st_ino, 300, hmode, task);
|
|
|
|
*volume=dbe->nwpath.volume;
|
|
|
|
} else result=-0xff;
|
|
|
|
} else free_dbe_p(dbe);
|
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nw_rename_file_dir(int namespace,
|
|
|
|
NW_HPATH *nwps, uint8 *pathes_s,
|
|
|
|
NW_HPATH *nwpd, uint8 *pathes_d,
|
|
|
|
int searchattrib,
|
|
|
|
int renameflag)
|
|
|
|
{
|
|
|
|
DIR_BASE_ENTRY *dbe_s = allocate_dbe_p(namespace);
|
|
|
|
DIR_BASE_ENTRY *dbe_d = (NULL != dbe_s) ? allocate_dbe_p(namespace) : NULL;
|
|
|
|
int result = -0xfb;
|
|
|
|
if (dbe_d &&
|
2011-11-13 00:38:57 +01:00
|
|
|
(result = build_base(namespace, nwps, pathes_s, dbe_s, 0, NULL)) > -1) {
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 last_part[258];
|
|
|
|
uint8 *unname_s=
|
2011-11-13 00:38:56 +01:00
|
|
|
(uint8*)nwpath_2_unix1(&(dbe_s->nwpath), 2, 1);
|
2011-11-13 00:38:57 +01:00
|
|
|
if ((result = build_base(namespace, nwpd, pathes_d, dbe_d,
|
2011-11-13 00:38:56 +01:00
|
|
|
1, last_part)) > -1) {
|
|
|
|
uint8 *unname_d =
|
2011-11-13 00:38:56 +01:00
|
|
|
(uint8*)nwpath_2_unix2(&(dbe_d->nwpath), 0, 1, last_part);
|
|
|
|
|
|
|
|
if (get_volume_options(dbe_s->nwpath.volume, 1) &
|
|
|
|
VOL_OPTION_READONLY) result= EROFS;
|
|
|
|
else if (get_volume_options(dbe_d->nwpath.volume, 1) &
|
|
|
|
VOL_OPTION_READONLY) result= EROFS;
|
|
|
|
|
|
|
|
else {
|
|
|
|
if (S_ISDIR(dbe_s->nwpath.statb.st_mode))
|
|
|
|
result = unx_mvdir(unname_s, unname_d);
|
|
|
|
else
|
|
|
|
result = unx_mvfile(unname_s, unname_d);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
XDPRINTF((5, 0, "Rename:%d '%s' -> '%s'", result, unname_s, unname_d));
|
|
|
|
|
|
|
|
xfree(unname_d);
|
|
|
|
switch (result) {
|
|
|
|
case 0 : break;
|
|
|
|
|
|
|
|
case EEXIST : result = -0x92; break;
|
2011-11-13 00:38:56 +01:00
|
|
|
case EROFS : result = -0x8b; break;
|
|
|
|
default : result = -0x8b;
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
if (!result) {
|
|
|
|
free_dbe_p(dbe_s);
|
|
|
|
if ((result=get_add_new_entry(dbe_d, last_part, 0)) > -1)
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
} else free_dbe_p(dbe_d);
|
|
|
|
xfree(unname_s);
|
|
|
|
} else free_dbe_p(dbe_s);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
|
2011-11-13 00:38:56 +01:00
|
|
|
{
|
|
|
|
int result = -0xfb; /* unknown request */
|
2011-11-13 00:38:57 +01:00
|
|
|
int ufunc = (int) *p++;
|
|
|
|
/* now p locates at 4 byte boundary ! */
|
2011-11-13 00:38:56 +01:00
|
|
|
int namespace = (int) *p; /* for most calls */
|
2011-11-13 00:38:56 +01:00
|
|
|
XDPRINTF((3, 0, "0x57 call ufunc=0x%x namespace=%d", ufunc, namespace));
|
|
|
|
switch (ufunc) {
|
|
|
|
case 0x01 : /* open creat file or subdir */
|
|
|
|
{
|
|
|
|
/* NW PATH STRUC */
|
|
|
|
int opencreatmode = *(p+1);
|
|
|
|
int attrib = (int) GET_16(p+2); /* LOW-HI */
|
|
|
|
uint32 infomask = GET_32(p+4); /* LOW-HI */
|
|
|
|
uint32 creatattrib = GET_32(p+8);
|
|
|
|
int access_rights = (int) GET_16(p+12); /* LOW-HI */
|
|
|
|
NW_HPATH nwpathstruct;
|
|
|
|
memcpy(&nwpathstruct, p+14, sizeof(nwpathstruct));
|
|
|
|
result = nw_open_creat_file_or_dir(namespace, opencreatmode,
|
|
|
|
attrib, infomask, creatattrib, access_rights,
|
|
|
|
&nwpathstruct, p+21, responsedata);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 0x02 : /* Initialize Search */
|
|
|
|
{
|
|
|
|
/* NW PATH STRUC */
|
2011-11-13 00:38:57 +01:00
|
|
|
NW_HPATH nwpathstruct;
|
|
|
|
memcpy(&nwpathstruct, p+2, sizeof(nwpathstruct));
|
|
|
|
result = nw_init_search(namespace,
|
|
|
|
&nwpathstruct,
|
|
|
|
p+9,
|
|
|
|
responsedata);
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x03 : /* Search for File or DIR */
|
|
|
|
{
|
|
|
|
/* NW PATH STRUC */
|
2011-11-13 00:38:56 +01:00
|
|
|
int datastream = (int) *(p+1);
|
2011-11-13 00:38:56 +01:00
|
|
|
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
|
|
|
|
uint32 infomask = GET_32(p+4); /* LOW-HI */
|
|
|
|
int volume = *(p+8);
|
|
|
|
uint32 basehandle = GET_32(p+9); /* LOW-HI */
|
|
|
|
uint32 sequence = GET_32(p+13); /* LOW-HI */
|
|
|
|
int len = *(p+17);
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 *path = p+18;
|
2011-11-13 00:38:56 +01:00
|
|
|
result = nw_search_file_dir(namespace, datastream,
|
|
|
|
searchattrib, infomask,
|
|
|
|
volume, basehandle, sequence,
|
|
|
|
len, path, responsedata);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
case 0x04 : /* rename File or Dir */
|
|
|
|
{
|
|
|
|
int renameflag = *(p+1);
|
|
|
|
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
|
|
|
|
NW_HPATH nwps;
|
|
|
|
NW_HPATH nwpd;
|
|
|
|
int size;
|
|
|
|
p+=4;
|
|
|
|
memcpy(&nwps, p, 7); p+=7;
|
|
|
|
memcpy(&nwpd, p, 7); p+=7;
|
|
|
|
size = get_comp_pathes_size(&nwps, p);
|
|
|
|
result = nw_rename_file_dir(namespace,
|
|
|
|
&nwps, p, &nwpd, p+size, searchattrib, renameflag);
|
|
|
|
}
|
|
|
|
break;
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
case 0x06 : /* Obtain File or Subdir Info */
|
|
|
|
{
|
|
|
|
int destnamspace = (int) p+1;
|
|
|
|
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
|
|
|
|
uint32 infomask = GET_32(p+4); /* LOW-HI */
|
|
|
|
NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8);
|
|
|
|
result = nw_optain_file_dir_info(namespace, nwpathstruct,
|
|
|
|
destnamspace,
|
|
|
|
searchattrib, infomask,
|
|
|
|
responsedata);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 0x07 : /* Modify File or Dir Info */
|
|
|
|
{
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x08 : /* Delete a File or Subdir */
|
|
|
|
{
|
|
|
|
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
|
|
|
|
NW_HPATH *nwpathstruct = (NW_HPATH *) (p+4);
|
|
|
|
result = nw_delete_file_dir(namespace, searchattrib, nwpathstruct);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x09 : /* Set short Dir Handle*/
|
|
|
|
{
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x0c : /* alloc short dir Handle */
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
int hmode = (int) GET_16(p+2); /* 0=p, 1=temp, 2=speztemp */
|
|
|
|
NW_HPATH *nwp = (NW_HPATH *)(p+4);
|
|
|
|
struct OUTPUT {
|
|
|
|
uint8 dir_handle;
|
|
|
|
uint8 volume;
|
|
|
|
uint8 reserved[4];
|
|
|
|
} *xdata= (struct OUTPUT*)responsedata;
|
|
|
|
int volume;
|
|
|
|
result = nw_alloc_short_dir_handle(namespace, hmode, nwp, task,
|
|
|
|
&volume);
|
|
|
|
if (result > -1) {
|
|
|
|
xdata->dir_handle = (uint8) result;
|
|
|
|
xdata->volume = (uint8) volume;
|
|
|
|
U32_TO_32(0L, xdata->reserved);
|
|
|
|
result=sizeof(struct OUTPUT);
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x15 : /* Get Path String from short dir new */
|
|
|
|
{
|
2011-11-13 00:38:56 +01:00
|
|
|
int dir_handle=(int) *(p+1);
|
|
|
|
result=nw_get_directory_path(dir_handle, responsedata+1);
|
|
|
|
if (result > -1) {
|
|
|
|
*responsedata=(uint8) result;
|
|
|
|
result+=1;
|
|
|
|
}
|
2011-11-13 00:38:56 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x16 : /* Generate Dir BASE and VolNumber */
|
|
|
|
{
|
|
|
|
NW_HPATH *nwpathstruct = (NW_HPATH *) (p+4);
|
|
|
|
struct OUTPUT {
|
|
|
|
uint8 ns_dir_base[4]; /* BASEHANDLE */
|
|
|
|
uint8 dos_dir_base[4]; /* BASEHANDLE */
|
|
|
|
uint8 volume; /* Volumenumber*/
|
|
|
|
} *xdata= (struct OUTPUT*)responsedata;
|
|
|
|
result = nw_generate_dir_path(namespace,
|
|
|
|
nwpathstruct, xdata->ns_dir_base, xdata->dos_dir_base);
|
|
|
|
if (result >-1 ) {
|
|
|
|
xdata->volume = result;
|
|
|
|
result = sizeof(struct OUTPUT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x18 : /* Get Name Spaces Loaded*/
|
|
|
|
{
|
|
|
|
int volume=*(p+2);
|
|
|
|
struct OUTPUT {
|
|
|
|
uint8 anz_name_spaces;
|
|
|
|
uint8 name_space_list[1];
|
|
|
|
} *xdata= (struct OUTPUT*)responsedata;
|
|
|
|
result=get_volume_options(volume, 0);
|
|
|
|
if (result >-1) {
|
2011-11-13 00:38:57 +01:00
|
|
|
xdata->anz_name_spaces = (uint8) 0;
|
|
|
|
if (result & VOL_NAMESPACE_DOS)
|
|
|
|
xdata->name_space_list[xdata->anz_name_spaces++]
|
|
|
|
= (uint8) NAME_DOS;
|
|
|
|
if (result & VOL_NAMESPACE_OS2)
|
|
|
|
xdata->name_space_list[xdata->anz_name_spaces++]
|
|
|
|
= (uint8) NAME_OS2;
|
|
|
|
if (result & VOL_NAMESPACE_NFS)
|
|
|
|
xdata->name_space_list[xdata->anz_name_spaces++]
|
|
|
|
= (uint8) NAME_NFS;
|
2011-11-13 00:38:56 +01:00
|
|
|
result=xdata->anz_name_spaces+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x1a : /* Get Huge NS Info new*/
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x1c : /* GetFullPathString new*/
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x1d : /* GetEffDirRights new */
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default : result = -0xfb; /* unknown request */
|
|
|
|
} /* switch */
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
|
|
|
|
int handle_func_0x56(uint8 *p, uint8 *responsedata, int task)
|
|
|
|
/* extended attribute calls */
|
|
|
|
{
|
|
|
|
int result = -0xfb; /* unknown request */
|
|
|
|
int ufunc = (int) *p++; /* now p locates at 4 byte boundary */
|
|
|
|
XDPRINTF((3, 0, "0x56 call ufunc=0x%x", ufunc));
|
|
|
|
switch (ufunc) {
|
2011-11-13 00:38:57 +01:00
|
|
|
#if 1
|
|
|
|
case 0x01 : /* close extended attribute handle */
|
|
|
|
{
|
|
|
|
uint32 ea_handle=GET_BE32(p+2);
|
|
|
|
result=0; /* dummy */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x02 : /* write extended attribute handle */
|
|
|
|
{
|
|
|
|
result=0; /* dummy */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
case 0x03 : /* read extended attribute */
|
|
|
|
{
|
2011-11-13 00:38:57 +01:00
|
|
|
int flags = GET_16(p); /* LOW-HIGH */
|
2011-11-13 00:38:56 +01:00
|
|
|
/* next 2 entries only if flags bits 0-1 = 00 */
|
2011-11-13 00:38:57 +01:00
|
|
|
/* (~(flags & 3)) volume + basehandle */
|
|
|
|
/* ( flag s & 2) eahandle + basehandle */
|
2011-11-13 00:38:56 +01:00
|
|
|
int volume = (int)GET_32(p+2);
|
|
|
|
uint32 basehandle = (int)GET_32(p+6);
|
2011-11-13 00:38:57 +01:00
|
|
|
|
|
|
|
uint32 readpos = GET_32(p+10);
|
|
|
|
uint32 size = GET_32(p+14);
|
|
|
|
uint16 keylen = GET_16(p+18); /* LOW-HIGH */
|
2011-11-13 00:38:56 +01:00
|
|
|
struct OUTPUT {
|
2011-11-13 00:38:57 +01:00
|
|
|
uint8 errorcode[4]; /* LOW-HIGH */
|
|
|
|
uint8 ttl_v_length[4]; /* LOW-HIGH */
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 ea_handle[4]; /* ???? */
|
|
|
|
uint8 access[4]; /* ???? */
|
2011-11-13 00:38:57 +01:00
|
|
|
uint8 value_length[2]; /* LOW-HIGH */
|
2011-11-13 00:38:56 +01:00
|
|
|
uint8 value[2];
|
|
|
|
} *xdata= (struct OUTPUT*)responsedata;
|
|
|
|
memset(xdata, 0, sizeof(struct OUTPUT));
|
2011-11-13 00:38:57 +01:00
|
|
|
U32_TO_32(0xc9, xdata->errorcode); /* NO extended Attributes */
|
2011-11-13 00:38:56 +01:00
|
|
|
result = sizeof(struct OUTPUT);
|
|
|
|
}
|
|
|
|
break;
|
2011-11-13 00:38:57 +01:00
|
|
|
|
|
|
|
case 0x04 : /* enumerate extended attributes */
|
|
|
|
{
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x05 : /* duplicate extended attributes */
|
|
|
|
{
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2011-11-13 00:38:56 +01:00
|
|
|
#endif
|
|
|
|
default : result = -0xfb; /* unknown request */
|
|
|
|
} /* switch */
|
|
|
|
return(result);
|
|
|
|
}
|
2011-11-13 00:38:55 +01:00
|
|
|
#endif
|