mars_nwe-0.99.pl06

This commit is contained in:
Mario Fetka 2011-11-13 00:38:59 +01:00
parent 0c09c074ef
commit 5c18363271
29 changed files with 1088 additions and 282 deletions

298
connect.c
View File

@ -1,5 +1,5 @@
/* connect.c 28-Nov-97 */ /* connect.c 01-Feb-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -45,13 +45,16 @@ static int act_umode_file=0;
#include "nwfname.h" #include "nwfname.h"
#include "nwvolume.h" #include "nwvolume.h"
#include "nwattrib.h"
#include "nwfile.h" #include "nwfile.h"
#include "nwconn.h" #include "nwconn.h"
#include "namspace.h"
#include "connect.h" #include "connect.h"
typedef struct { typedef struct {
ino_t inode; /* Unix Inode dieses Verzeichnisses */ int dev; /* unix dev */
ino_t inode; /* unix inode */
time_t timestamp; /* Zeitmarke */ time_t timestamp; /* Zeitmarke */
uint8 *path; /* path ab Volume */ uint8 *path; /* path ab Volume */
uint8 volume; /* Welches Volume */ uint8 volume; /* Welches Volume */
@ -63,9 +66,9 @@ typedef struct {
NW_DIR dirs[MAX_NW_DIRS]; NW_DIR dirs[MAX_NW_DIRS];
int used_dirs=0; int used_dirs=0;
int act_uid=-1; int act_uid=-1; /* unix uid 0=root */
int act_gid=-1; int act_gid=-1; /* unix gid */
int act_obj_id=0L; /* not login */ int act_obj_id=0L; /* mars_nwe UID, 0=not logged in, 1=supervisor */
int entry8_flags=0; /* special flags, see examples nw.ini, entry 8 */ int entry8_flags=0; /* special flags, see examples nw.ini, entry 8 */
static gid_t *act_grouplist=NULL; /* first element is counter !! */ static gid_t *act_grouplist=NULL; /* first element is counter !! */
@ -77,10 +80,11 @@ static int connect_is_init = 0;
typedef struct { typedef struct {
DIR *f; DIR *f;
char unixname[256]; /* kompletter unixname */ char unixname[256]; /* full unixname */
int dev; /* Unix dev */
ino_t inode; /* Unix Inode */ ino_t inode; /* Unix Inode */
time_t timestamp; /* f<EFBFBD>r letzte Allocierung */ time_t timestamp; /* last allocation */
char *kpath; /* Ein Zeichen nach unixname */ char *kpath; /* one char after unixname */
int vol_options; /* searchoptions */ int vol_options; /* searchoptions */
int volume; /* Volume Number */ int volume; /* Volume Number */
@ -127,7 +131,7 @@ static char *build_unix_name(NW_PATH *nwpath, int modus)
} }
static int new_dir_handle(ino_t inode, NW_PATH *nwpath) static int new_dir_handle(int dev, ino_t inode, NW_PATH *nwpath)
/* /*
* RETURN=errorcode (<0) or dir_handle * RETURN=errorcode (<0) or dir_handle
*/ */
@ -147,7 +151,8 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
if (!dh->inode) { if (!dh->inode) {
if (!nhandle) if (!nhandle)
nhandle = rethandle+1; nhandle = rethandle+1;
} else if (dh->inode == inode && dh->volume == nwpath->volume){ } else if (dh->dev == dev && dh->inode == inode
&& dh->volume == nwpath->volume){
nhandle = rethandle+1; nhandle = rethandle+1;
break; break;
} else if (dh->timestamp < last_time){ } else if (dh->timestamp < last_time){
@ -177,6 +182,7 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){ if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){
dh->volume = nwpath->volume; dh->volume = nwpath->volume;
dh->vol_options = nw_volumes[dh->volume].options; dh->vol_options = nw_volumes[dh->volume].options;
dh->dev = dev;
dh->inode = inode; dh->inode = inode;
dh->timestamp = akttime; dh->timestamp = akttime;
dh->sequence = 0; dh->sequence = 0;
@ -877,12 +883,11 @@ static int build_path( NW_PATH *path,
return(0); return(0);
} }
static int nw_path_ok(NW_PATH *nwpath) static int nw_path_ok(NW_PATH *nwpath, struct stat *stbuff)
/* returns UNIX inode of path */ /* returns UNIX inode of path */
{ {
int j = 0; int j = 0;
NW_DIR *d=&(dirs[0]); NW_DIR *d=&(dirs[0]);
struct stat stbuff;
int result=0; int result=0;
if ((!act_obj_id) && !(entry8_flags & 1)) { if ((!act_obj_id) && !(entry8_flags & 1)) {
@ -904,21 +909,24 @@ static int nw_path_ok(NW_PATH *nwpath)
while (j++ < (int)used_dirs){ while (j++ < (int)used_dirs){
if (d->inode && d->volume == nwpath->volume if (d->inode && d->volume == nwpath->volume
&& !strcmp((char*)nwpath->path, (char*)d->path)){ && !strcmp((char*)nwpath->path, (char*)d->path)){
stbuff->st_ino = d->inode;
stbuff->st_dev = d->dev;
return(d->inode); return(d->inode);
} }
d++; d++;
} /* while */ } /* while */
if (!s_stat(build_unix_name(nwpath, 1 | 2 ), &stbuff, NULL) if (!s_stat(build_unix_name(nwpath, 1 | 2 ), stbuff, NULL)
&& S_ISDIR(stbuff.st_mode)) && S_ISDIR(stbuff->st_mode))
return(stbuff.st_ino); return(stbuff->st_ino);
result = -0x9c; /* wrong path */ result = -0x9c; /* wrong path */
} }
XDPRINTF((4,0x10, "NW_PATH_OK failed:`%s`", conn_get_nwpath_name(nwpath))); XDPRINTF((4,0x10, "NW_PATH_OK failed:`%s`", conn_get_nwpath_name(nwpath)));
return(result); return(result);
} }
static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ static int build_dir_name(NW_PATH *nwpath, /* gets complete path */
int dir_handle) /* search with dirhandle */ struct stat *stbuff,
int dir_handle) /* search with dirhandle */
/* return -completition code or inode */ /* return -completition code or inode */
{ {
@ -954,7 +962,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
int state = 0; int state = 0;
while ((!completition) && (w = *p++) > 0){ while ((!completition) && (w = *p++) > 0){
if (!state){ if (!state){
XDPRINTF((5,0,"in build_verz_name path=:%s:", nwpath->path)); XDPRINTF((5,0,"in build_dir_name path=:%s:", nwpath->path));
if (w == '.') state = 20; if (w == '.') state = 20;
else if (w == '/') state = 30; else if (w == '/') state = 30;
else state++; else state++;
@ -1036,13 +1044,13 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
memcpy(nwpath->fn, pp+pathlen, fnlen); memcpy(nwpath->fn, pp+pathlen, fnlen);
} }
} else return(-0x98); /* wrong volume */ } else return(-0x98); /* wrong volume */
completition = nw_path_ok(nwpath); completition = nw_path_ok(nwpath, stbuff);
} }
return(completition); return(completition);
} }
int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, static int conn_get_kpl_path(NW_PATH *nwpath, struct stat *stbuff,
uint8 *data, int len, int only_dir) int dirhandle, uint8 *data, int len, int only_dir)
/* /*
* if ok then the inode of dir will be returned * if ok then the inode of dir will be returned
* else a negativ errcode will be returned * else a negativ errcode will be returned
@ -1051,7 +1059,7 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
int completition = build_path(nwpath, data, len, only_dir); int completition = build_path(nwpath, data, len, only_dir);
XDPRINTF((5, 0, "compl=0x%x, conn_get_kpl_path %s", XDPRINTF((5, 0, "compl=0x%x, conn_get_kpl_path %s",
completition, conn_get_nwpath_name(nwpath))); completition, conn_get_nwpath_name(nwpath)));
if (!completition) completition = build_verz_name(nwpath, dirhandle); if (!completition) completition = build_dir_name(nwpath, stbuff, dirhandle);
return(completition); return(completition);
} }
@ -1060,10 +1068,11 @@ int conn_get_full_path(int dirhandle, uint8 *data, int len,
/* returns path in form VOLUME:PATH */ /* returns path in form VOLUME:PATH */
{ {
NW_PATH nwpath; NW_PATH nwpath;
struct stat stbuff;
int result = build_path(&nwpath, data, len, 0); int result = build_path(&nwpath, data, len, 0);
fullpath[0]='\0'; fullpath[0]='\0';
if (!result) if (!result)
result = build_verz_name(&nwpath, dirhandle); result = build_dir_name(&nwpath, &stbuff, dirhandle);
if (result > -1) { if (result > -1) {
uint8 *p=(*nwpath.path=='/') ? nwpath.path+1 : nwpath.path; uint8 *p=(*nwpath.path=='/') ? nwpath.path+1 : nwpath.path;
int len=sprintf(fullpath, "%s:%s", int len=sprintf(fullpath, "%s:%s",
@ -1087,9 +1096,10 @@ int conn_get_kpl_unxname(char *unixname,
*/ */
{ {
NW_PATH nwpath; NW_PATH nwpath;
struct stat stbuff;
int completition = build_path(&nwpath, data, len, 0); int completition = build_path(&nwpath, data, len, 0);
if (!completition) if (!completition)
completition = build_verz_name(&nwpath, dirhandle); completition = build_dir_name(&nwpath, &stbuff, dirhandle);
if (completition > -1) { if (completition > -1) {
if (unixname) if (unixname)
strcpy(unixname, build_unix_name(&nwpath, 0)); strcpy(unixname, build_unix_name(&nwpath, 0));
@ -1151,6 +1161,7 @@ time_t nw_2_un_time(uint8 *d, uint8 *t)
return(mktime(&s_tm)); return(mktime(&s_tm));
} }
#if !NEW_ATTRIB_HANDLING
int un_nw_attrib(struct stat *stb, int attrib, int mode) int un_nw_attrib(struct stat *stb, int attrib, int mode)
/* mode: 0 = un2nw , 1 = nw2un */ /* mode: 0 = un2nw , 1 = nw2un */
{ {
@ -1166,6 +1177,7 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode)
if (!mode) { if (!mode) {
/* UNIX access -> NW access */ /* UNIX access -> NW access */
if (!is_dir) { if (!is_dir) {
attrib = FILE_ATTR_A; attrib = FILE_ATTR_A;
} else { } else {
@ -1190,6 +1202,7 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode)
} else { } else {
/* NW access -> UNIX access */ /* NW access -> UNIX access */
int mode = S_IRUSR | S_IRGRP; int mode = S_IRUSR | S_IRGRP;
#if 0 #if 0
/* this is sometimes very BAD */ /* this is sometimes very BAD */
if (attrib & FILE_ATTR_H) /* hidden */ if (attrib & FILE_ATTR_H) /* hidden */
@ -1211,16 +1224,17 @@ int un_nw_attrib(struct stat *stb, int attrib, int mode)
else else
stb->st_mode &= ~S_IXGRP; stb->st_mode &= ~S_IXGRP;
} }
return(stb->st_mode); return(stb->st_mode);
} }
} }
#endif
int un_nw_rights(struct stat *stb) int un_nw_rights(struct stat *stb)
/* returns eff rights of file/dir */ /* returns eff rights of file/dir */
/* needs some more work */ /* needs some more work */
{ {
int rights=0xfb; /* first all rights, but not TRUSTEE_O */ /* int rights=0xfb; first all rights, but not TRUSTEE_O */
int rights=0xff; /* first all, pconsole needs TRUSTEE_O */
if (act_uid) { if (act_uid) {
/* if not root */ /* if not root */
int is_dir = S_ISDIR(stb->st_mode); int is_dir = S_ISDIR(stb->st_mode);
@ -1250,9 +1264,21 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
NW_PATH *nwpath) NW_PATH *nwpath)
{ {
int voloptions=get_volume_options(nwpath->volume); int voloptions=get_volume_options(nwpath->volume);
uint32 dwattrib;
strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name));
f->attrib=0; /* d->name could be too long */ f->attrib=0; /* d->name could be too long */
up_fn(f->name); up_fn(f->name);
#if NEW_ATTRIB_HANDLING
dwattrib = get_nw_attrib_dword(stb, voloptions);
f->attrib = (uint8)(dwattrib & 0xff);
# if 0
/* is this OK or next ??? */
dwattrib >>=8;
f->ext_attrib = (uint8)(dwattrib & 0xff);
# else
f->ext_attrib = 0;
# endif
#else
if (voloptions & VOL_OPTION_IS_PIPE) if (voloptions & VOL_OPTION_IS_PIPE)
f->attrib = FILE_ATTR_SHARE; f->attrib = FILE_ATTR_SHARE;
else else
@ -1261,6 +1287,7 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
(int)f->attrib, conn_get_nwpath_name(nwpath), (int)f->attrib, conn_get_nwpath_name(nwpath),
stb->st_uid, stb->st_gid)); stb->st_uid, stb->st_gid));
f->ext_attrib = 0; f->ext_attrib = 0;
#endif
un_date_2_nw(stb->st_mtime, f->create_date, 1); un_date_2_nw(stb->st_mtime, f->create_date, 1);
un_date_2_nw(stb->st_atime, f->acces_date, 1); un_date_2_nw(stb->st_atime, f->acces_date, 1);
un_date_2_nw(stb->st_mtime, f->modify_date, 1); un_date_2_nw(stb->st_mtime, f->modify_date, 1);
@ -1272,16 +1299,24 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb,
NW_PATH *nwpath) NW_PATH *nwpath)
{ {
int voloptions=get_volume_options(nwpath->volume);
XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath))); XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath)));
strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name)); strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name));
d->attrib=0; /* d->name could be too long */ d->attrib=0; /* d->name could be too long */
up_fn(d->name); up_fn(d->name);
d->attrib = (uint8) un_nw_attrib(stb, 0, 0);
#if 0 /* changed: 02-Nov-96 */ #if NEW_ATTRIB_HANDLING
d->ext_attrib = 0xff; /* effektive rights ?? */ d->attrib = (uint8)get_nw_attrib_dword(stb, voloptions);
#else
d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */ d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */
#endif #else
d->attrib = (uint8) un_nw_attrib(stb, 0, 0);
# if 0 /* changed: 02-Nov-96 */
d->ext_attrib = 0xff; /* effektive rights ?? */
# else
d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */
# endif
#endif
un_date_2_nw(stb->st_mtime, d->create_date, 1); un_date_2_nw(stb->st_mtime, d->create_date, 1);
un_time_2_nw(stb->st_mtime, d->create_time, 1); un_time_2_nw(stb->st_mtime, d->create_time, 1);
U32_TO_BE32(get_file_owner(stb), d->owner_id); U32_TO_BE32(get_file_owner(stb), d->owner_id);
@ -1302,7 +1337,8 @@ static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs)
int nw_delete_datei(int dir_handle, uint8 *data, int len) int nw_delete_datei(int dir_handle, uint8 *data, int len)
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0);
if (completition > -1) { if (completition > -1) {
completition = func_search_entry(&nwpath, 0x6, do_delete_file, NULL); completition = func_search_entry(&nwpath, 0x6, do_delete_file, NULL);
if (completition < 0) return(completition); if (completition < 0) return(completition);
@ -1316,11 +1352,11 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs)
char unname[256]; char unname[256];
int result=0; int result=0;
NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf; NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf;
int voloption; int voloptions;
strcpy(unname, build_unix_name(nwpath, 0)); strcpy(unname, build_unix_name(nwpath, 0));
if ((voloption = get_volume_options(nwpath->volume)) & VOL_OPTION_IS_PIPE){ if ((voloptions = get_volume_options(nwpath->volume)) & VOL_OPTION_IS_PIPE){
;; /* don't change 'pipe commands' */ ;; /* don't change 'pipe commands' */
} else if (voloption & VOL_OPTION_READONLY) { } else if (voloptions & VOL_OPTION_READONLY) {
result=(-0x8c); /* no modify rights */ result=(-0x8c); /* no modify rights */
} else { } else {
struct utimbuf ut; struct utimbuf ut;
@ -1329,10 +1365,24 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs)
S_STATB stb; S_STATB stb;
#endif #endif
ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time); ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time);
if ( 0 == (result=s_stat(unname, &statb, &stb)) && if (0 == (result=s_stat(unname, &statb, &stb))) {
0 == (result=s_utime(unname, &ut, &stb))){ #if NEW_ATTRIB_HANDLING
result = s_chmod(unname, result = set_nw_attrib_byte(&statb, voloptions, (int) f->attrib);
if (result < 0 && !(f->attrib & FILE_ATTR_R)) {
result = s_chmod(unname, statb.st_mode | S_IWUSR, &stb);
if (!result) {
statb.st_mode |= S_IWUSR;
result = set_nw_attrib_byte(&statb, voloptions, (int)f->attrib);
}
}
if (!result)
result=s_utime(unname, &ut, &stb);
#else
if (0 == (result=s_utime(unname, &ut, &stb))){
result = s_chmod(unname,
un_nw_attrib(&statb, (int)f->attrib, 1), &stb); un_nw_attrib(&statb, (int)f->attrib, 1), &stb);
}
#endif
} }
if (result) if (result)
result= (-0x8c); /* no modify rights */ result= (-0x8c); /* no modify rights */
@ -1345,7 +1395,8 @@ int nw_set_file_information(int dir_handle, uint8 *data, int len,
int searchattrib, NW_FILE_INFO *f) int searchattrib, NW_FILE_INFO *f)
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0);
if (completition > -1) { if (completition > -1) {
FUNC_SEARCH fs; FUNC_SEARCH fs;
fs.ubuf = (uint8*)f; fs.ubuf = (uint8*)f;
@ -1357,30 +1408,42 @@ int nw_set_file_information(int dir_handle, uint8 *data, int len,
return(completition); return(completition);
} }
int nw_chmod_datei(int dir_handle, uint8 *data, int len, int nw_set_file_attributes(int dir_handle, uint8 *data, int len,
int attrib, int access) int attrib, int newattrib)
{ {
char unname[256]; char unname[256];
struct stat stbuff; struct stat stbuff;
int completition=-0x9c; int completition=-0x9c;
NW_PATH nwpath; NW_PATH nwpath;
int voloptions;
#if PERSISTENT_SYMLINKS #if PERSISTENT_SYMLINKS
S_STATB stb; S_STATB stb;
#endif #endif
build_path(&nwpath, data, len, 0); build_path(&nwpath, data, len, 0);
if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */ if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */
completition = build_verz_name(&nwpath, dir_handle); completition = build_dir_name(&nwpath, &stbuff, dir_handle);
} }
if (completition < 0) return(completition); if (completition < 0) return(completition);
voloptions=get_volume_options(nwpath.volume);
strcpy(unname, build_unix_name(&nwpath, 2)); strcpy(unname, build_unix_name(&nwpath, 2));
XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", access, unname)); XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", newattrib, unname));
if (!s_stat(unname, &stbuff, &stb)){ if (!s_stat(unname, &stbuff, &stb)){
int result = s_chmod(unname, un_nw_attrib(&stbuff, access, 1), &stb); #if NEW_ATTRIB_HANDLING
int result = set_nw_attrib_byte(&stbuff, voloptions, newattrib);
if (result < 0 && !(newattrib & FILE_ATTR_R)) {
result = s_chmod(unname, stbuff.st_mode | S_IWUSR, &stb);
if (!result) {
stbuff.st_mode |= S_IWUSR;
result = set_nw_attrib_byte(&stbuff, voloptions, newattrib);
}
}
#else
int result = s_chmod(unname, un_nw_attrib(&stbuff, newattrib, 1), &stb);
#endif
return( (result != 0) ? -0x8c : 0); /* no modify rights */ return( (result != 0) ? -0x8c : 0); /* no modify rights */
} }
return(-0x9c); /* wrong path */ return(-0x9c); /* wrong path */
} }
@ -1408,8 +1471,18 @@ int nw_creat_node(int volnr, uint8 *unname, int mode)
return(0); return(0);
} }
} else { /* file */ } else { /* file */
int fd=(mode & 2) ? open(unname, O_CREAT|O_TRUNC|O_RDWR, 0777) int fd=-1;
: creat(unname, 0777); if (mode & 2) {
struct stat stbuff;
int voloptions = get_volume_options(volnr);
if (!stat(unname, &stbuff)) { /* exists */
if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R)
fd=-2;
}
if (fd!=-2)
fd=open(unname, O_CREAT|O_TRUNC|O_RDWR, 0777);
} else
fd = creat(unname, 0777);
if (fd < 0 && (mode & 8)) { /* creat always */ if (fd < 0 && (mode & 8)) { /* creat always */
if ( (!seteuid(0)) && (-1 < (fd = if ( (!seteuid(0)) && (-1 < (fd =
@ -1438,13 +1511,16 @@ int nw_creat_node(int volnr, uint8 *unname, int mode)
int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, !mode); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff,
dir_handle, data, len, !mode);
if (completition > -1) { if (completition > -1) {
char unname[256]; char unname[256];
int voloptions;
strcpy(unname, build_unix_name(&nwpath, 2)); strcpy(unname, build_unix_name(&nwpath, 2));
if (get_volume_options(nwpath.volume) & VOL_OPTION_READONLY) if ((voloptions=get_volume_options(nwpath.volume)) & VOL_OPTION_READONLY)
return(mode ? -0x84 : -0x8a); return(mode ? -0x84 : -0x8a);
if (mode) { if (mode) {
XDPRINTF((5,0,"MKDIR dirname:%s:", unname)); XDPRINTF((5,0,"MKDIR dirname:%s:", unname));
if (!nw_creat_node(nwpath.volume, unname, 1)) if (!nw_creat_node(nwpath.volume, unname, 1))
@ -1455,9 +1531,13 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */
} else { /* rmdir */ } else { /* rmdir */
int j = -1; int j = -1;
if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R)
return(-0x8a); /* don't delete 'readonly' */
while (++j < (int)anz_dirhandles){ while (++j < (int)anz_dirhandles){
DIR_HANDLE *dh=&(dir_handles[j]); DIR_HANDLE *dh=&(dir_handles[j]);
if (dh->inode == completition && dh->f != (DIR*) NULL) { if ( dh->dev == stbuff.st_dev &&
dh->inode == stbuff.st_ino && dh->f != (DIR*) NULL) {
closedir(dh->f); closedir(dh->f);
dh->f = (DIR*)NULL; dh->f = (DIR*)NULL;
} }
@ -1468,7 +1548,8 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
NW_DIR *d=&(dirs[0]); NW_DIR *d=&(dirs[0]);
j = 0; j = 0;
while (j++ < (int)used_dirs){ while (j++ < (int)used_dirs){
if (d->inode == completition) d->inode = 0; if ( d->dev == stbuff.st_dev &&
d->inode == stbuff.st_ino) d->inode = 0;
d++; d++;
} }
j = -1; j = -1;
@ -1476,6 +1557,7 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
DIR_HANDLE *dh=&(dir_handles[j]); DIR_HANDLE *dh=&(dir_handles[j]);
if (dh->inode == completition) free_dir_handle(j+1); if (dh->inode == completition) free_dir_handle(j+1);
} }
free_nw_ext_inode(stbuff.st_dev, stbuff.st_ino);
completition = 0; completition = 0;
} else if (errno == EEXIST) } else if (errno == EEXIST)
completition = -0xa0; /* dir not empty */ completition = -0xa0; /* dir not empty */
@ -1489,13 +1571,15 @@ int mv_file(int qdirhandle, uint8 *q, int qlen,
int zdirhandle, uint8 *z, int zlen) int zdirhandle, uint8 *z, int zlen)
{ {
NW_PATH quellpath; NW_PATH quellpath;
struct stat qstbuff;
NW_PATH zielpath; NW_PATH zielpath;
struct stat zstbuff;
int completition; int completition;
zlen=apply_wildcards(q, qlen, z, zlen); zlen=apply_wildcards(q, qlen, z, zlen);
completition=conn_get_kpl_path(&quellpath, qdirhandle, q, qlen, 0); completition=conn_get_kpl_path(&quellpath, &qstbuff, qdirhandle, q, qlen, 0);
if (completition > -1) { if (completition > -1) {
completition=conn_get_kpl_path(&zielpath, zdirhandle, z, zlen, 0); completition=conn_get_kpl_path(&zielpath, &zstbuff, zdirhandle, z, zlen, 0);
if (completition > -1) { if (completition > -1) {
int optq = get_volume_options(quellpath.volume); int optq = get_volume_options(quellpath.volume);
int optz = get_volume_options(zielpath.volume); int optz = get_volume_options(zielpath.volume);
@ -1529,8 +1613,12 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
uint8 *z, int zlen) uint8 *z, int zlen)
{ {
NW_PATH quellpath; NW_PATH quellpath;
struct stat qstbuff;
NW_PATH zielpath; NW_PATH zielpath;
int completition=conn_get_kpl_path(&quellpath, dir_handle, q, qlen, 0); #if 0
struct stat zstbuff;
#endif
int completition=conn_get_kpl_path(&quellpath, &qstbuff, dir_handle, q, qlen, 0);
if (completition > -1){ if (completition > -1){
#if 1 #if 1
/* I do not know anymore why I did these ??? */ /* I do not know anymore why I did these ??? */
@ -1544,7 +1632,7 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
*/ */
#else #else
/* and NOT these, perhaps this will also be ok ?! -- TODO -- */ /* and NOT these, perhaps this will also be ok ?! -- TODO -- */
completition=conn_get_kpl_path(&zielpath, dir_handle, z, zlen, 0); completition=conn_get_kpl_path(&zielpath, &zstbuff, dir_handle, z, zlen, 0);
#endif #endif
if (completition > -1) { if (completition > -1) {
int optq = get_volume_options(quellpath.volume); int optq = get_volume_options(quellpath.volume);
@ -1584,7 +1672,8 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
} }
static int change_dir_entry( NW_DIR *dir, int volume, static int change_dir_entry( NW_DIR *dir, int volume,
uint8 *path, ino_t inode, uint8 *path,
int dev, ino_t inode,
int driveletter, int is_temp, int driveletter, int is_temp,
int new_entry, int task) int new_entry, int task)
{ {
@ -1605,6 +1694,7 @@ static int change_dir_entry( NW_DIR *dir, int volume,
++len; ++len;
} }
*(dir->path+len) = '\0'; *(dir->path+len) = '\0';
dir->dev = dev;
dir->inode = inode; dir->inode = inode;
dir->volume = (uint8) volume; dir->volume = (uint8) volume;
dir->timestamp = time(NULL); dir->timestamp = time(NULL);
@ -1627,6 +1717,9 @@ void nw_exit_connect(void)
if (connect_is_init) { if (connect_is_init) {
init_file_module(-1); init_file_module(-1);
} }
#if WITH_NAME_SPACE_CALLS
exit_name_space_module();
#endif
} }
int nw_init_connect(void) int nw_init_connect(void)
@ -1642,6 +1735,8 @@ int nw_init_connect(void)
int what; int what;
int k = MAX_NW_DIRS; int k = MAX_NW_DIRS;
NW_DIR *d = &(dirs[0]); NW_DIR *d = &(dirs[0]);
int namspace_max_baseh=0;
int namspace_max_searchh=0;
strcpy((char*)nwlogin.path, (char*)login); strcpy((char*)nwlogin.path, (char*)login);
nwlogin.fn[0] = '\0'; nwlogin.fn[0] = '\0';
nwlogin.volume = 0; nwlogin.volume = 0;
@ -1695,15 +1790,21 @@ int nw_init_connect(void)
} }
} else if (50 == what) { } else if (50 == what) {
init_nwfname(buff); init_nwfname(buff);
} else if (63 == what) { /* MAX_DIR_BASE */
namspace_max_baseh=atoi(buff);
} else if (68 == what) { /* USE_MMAP */ } else if (68 == what) { /* USE_MMAP */
use_mmap=atoi(buff); use_mmap=atoi(buff);
} else if (80 == what) {
namspace_max_searchh=atoi(buff);
} else if (what == 103) { /* Debug */ } else if (what == 103) { /* Debug */
get_debug_level(buff); get_debug_level(buff);
} }
} /* while */ } /* while */
nw_init_volumes(f); nw_init_volumes(f);
fclose(f); fclose(f);
#if WITH_NAME_SPACE_CALLS
init_name_space_module(namspace_max_baseh, namspace_max_searchh);
#endif
if (used_nw_volumes < 1) { if (used_nw_volumes < 1) {
errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL);
return(-1); return(-1);
@ -1715,7 +1816,8 @@ int nw_init_connect(void)
"UnixPath=`%s`", build_unix_name(&nwlogin, 0)); "UnixPath=`%s`", build_unix_name(&nwlogin, 0));
return(-1); return(-1);
} }
(void)change_dir_entry(&(dirs[0]), 0, nwlogin.path, stbuff.st_ino, (void)change_dir_entry(&(dirs[0]), 0, nwlogin.path,
stbuff.st_dev, stbuff.st_ino,
0, 0, 1, 0); 0, 0, 1, 0);
/* first Handle must be known und must not be temp */ /* first Handle must be known und must not be temp */
/* and has no Drive-Character */ /* and has no Drive-Character */
@ -1760,7 +1862,7 @@ int nw_free_handles(int task)
return(0); return(0);
} }
int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp, int task) int xinsert_new_dir(int volume, uint8 *path, int dev, int inode, int drive, int is_temp, int task)
{ {
int j = 0; int j = 0;
int freehandle = 0; int freehandle = 0;
@ -1786,17 +1888,18 @@ int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp,
#endif #endif
if (freehandle){ if (freehandle){
(void)change_dir_entry(&(dirs[freehandle-1]), (void)change_dir_entry(&(dirs[freehandle-1]),
volume, path, inode, volume, path, dev, inode,
drive, is_temp, 1, task); drive, is_temp, 1, task);
while (used_dirs > freehandle && !dirs[used_dirs-1].inode) used_dirs--; while (used_dirs > freehandle && !dirs[used_dirs-1].inode) used_dirs--;
return(freehandle); return(freehandle);
} else return(-0x9d); /* no dir Handles */ } else return(-0x9d); /* no dir Handles */
} }
int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) static int insert_new_dir(NW_PATH *nwpath, int dev, int inode,
int drive, int is_temp, int task)
{ {
return(xinsert_new_dir(nwpath->volume, nwpath->path, return(xinsert_new_dir(nwpath->volume, nwpath->path,
inode, drive, is_temp, task)); dev, inode, drive, is_temp, task));
} }
@ -1806,7 +1909,8 @@ int nw_search(uint8 *info, uint32 *fileowner,
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dirhandle, data, len, 0); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, len, 0);
XDPRINTF((5,0,"nw_search path:%s:, fn:%s:, completition:0x%x", XDPRINTF((5,0,"nw_search path:%s:, fn:%s:, completition:0x%x",
nwpath.path, nwpath.fn, completition)); nwpath.path, nwpath.fn, completition));
if (completition > -1) { if (completition > -1) {
@ -1889,9 +1993,11 @@ int nw_alloc_dir_handle( int dir_handle, /* source directory handle */
int task) /* Prozess Task */ int task) /* Prozess Task */
{ {
NW_PATH nwpath; NW_PATH nwpath;
int inode=conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); struct stat stbuff;
int inode=conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1);
if (inode > -1) if (inode > -1)
inode = insert_new_dir(&nwpath, inode, driveletter, is_temphandle, task); inode = insert_new_dir(&nwpath, stbuff.st_dev, stbuff.st_ino,
driveletter, is_temphandle, task);
XDPRINTF((2,0,"Allocate %shandle:%s, Qhandle=%d, drive=%d, Task=%d, result=0x%x", XDPRINTF((2,0,"Allocate %shandle:%s, Qhandle=%d, drive=%d, Task=%d, result=0x%x",
(is_temphandle) ? "Temp" : "Perm", conn_get_nwpath_name(&nwpath), (is_temphandle) ? "Temp" : "Perm", conn_get_nwpath_name(&nwpath),
dir_handle, driveletter, task, inode)); dir_handle, driveletter, task, inode));
@ -1913,12 +2019,13 @@ int nw_open_dir_handle( int dir_handle,
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1);
if (completition > -1) { if (completition > -1) {
XDPRINTF((5,0,"NW_OPEN_DIR: completition = 0x%x; nwpath= %s", XDPRINTF((5,0,"NW_OPEN_DIR: completition = 0x%x; nwpath= %s",
(int)completition, conn_get_nwpath_name(&nwpath) )); (int)completition, conn_get_nwpath_name(&nwpath) ));
completition = new_dir_handle((ino_t)completition, &nwpath); completition = new_dir_handle(stbuff.st_dev, stbuff.st_ino, &nwpath);
if (completition > -1) { if (completition > -1) {
struct stat stb; struct stat stb;
DIR_HANDLE *dh = &(dir_handles[completition-1]); DIR_HANDLE *dh = &(dir_handles[completition-1]);
@ -1956,7 +2063,7 @@ int nw_free_dir_handle(int dir_handle, int task)
} }
int alter_dir_handle(int targetdir, int volume, uint8 *path, int alter_dir_handle(int targetdir, int volume, uint8 *path,
int inode, int task) int dev, int inode, int task)
/* targetdir will be changed */ /* targetdir will be changed */
{ {
if (targetdir > 0 && --targetdir < used_dirs if (targetdir > 0 && --targetdir < used_dirs
@ -1965,7 +2072,7 @@ int alter_dir_handle(int targetdir, int volume, uint8 *path,
XDPRINTF((5,0,"Change dhandle:%d(%d) -> '%d:%s'", targetdir+1, task, XDPRINTF((5,0,"Change dhandle:%d(%d) -> '%d:%s'", targetdir+1, task,
volume, path)); volume, path));
return(change_dir_entry(&dirs[targetdir], return(change_dir_entry(&dirs[targetdir],
volume, path, inode, volume, path, dev, inode,
-1, -1, 0, task)); -1, -1, 0, task));
/* here the existing handle is only modified */ /* here the existing handle is only modified */
} else return(-0x9b); /* BAD DIR Handle */ } else return(-0x9b); /* BAD DIR Handle */
@ -1977,10 +2084,11 @@ int nw_set_dir_handle(int targetdir, int dir_handle,
/* targetdirs gets path of dirhandle + data */ /* targetdirs gets path of dirhandle + data */
{ {
NW_PATH nwpath; NW_PATH nwpath;
int inode = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); struct stat stbuff;
int inode = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 1);
if (inode > -1) if (inode > -1)
inode = alter_dir_handle(targetdir, nwpath.volume, nwpath.path, inode = alter_dir_handle(targetdir, nwpath.volume, nwpath.path,
inode, task); stbuff.st_dev, stbuff.st_ino, task);
return(inode); /* invalid PATH */ return(inode); /* invalid PATH */
} }
@ -2020,7 +2128,7 @@ int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus)
char unname[256]; char unname[256];
struct stat stbuff; struct stat stbuff;
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len,
(modus) ? 0 : 1); (modus) ? 0 : 1);
if (completition < 0) return(completition); if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 0)); strcpy(unname, build_unix_name(&nwpath, 0));
@ -2041,9 +2149,9 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len,
*/ */
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len, 0);
if (completition > -1) { if (completition > -1) {
struct stat stbuff;
completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0), completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0),
&stbuff, attrib, access, creatmode, task); &stbuff, attrib, access, creatmode, task);
@ -2161,10 +2269,14 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
/* Attribute */ /* Attribute */
/* 0x20 Archive Flag */ /* 0x20 Archive Flag */
/* 0x80 Sharable */ /* 0x80 Sharable */
#if NEW_ATTRIB_HANDLING
f->attributes[0] = (uint8) get_nw_attrib_dword(stb, voloptions);
#else
if (voloptions & VOL_OPTION_IS_PIPE) if (voloptions & VOL_OPTION_IS_PIPE)
f->attributes[0] = FILE_ATTR_SHARE; f->attributes[0] = FILE_ATTR_SHARE;
else else
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
#endif
un_date_2_nw(stb->st_mtime, f->created.date, 0); un_date_2_nw(stb->st_mtime, f->created.date, 0);
un_time_2_nw(stb->st_mtime, f->created.time, 0); un_time_2_nw(stb->st_mtime, f->created.time, 0);
U32_TO_BE32(nw_owner, f->created.id); U32_TO_BE32(nw_owner, f->created.id);
@ -2183,11 +2295,16 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
uint8 *path) uint8 *path)
{ {
uint8 spath[14]; uint8 spath[14];
int voloptions=get_volume_options(volume);
f->namlen=min(strlen((char*)path), 12); f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12); strmaxcpy(spath, path, 12);
up_fn(spath); up_fn(spath);
strncpy((char*)f->name, (char*)spath, f->namlen); strncpy((char*)f->name, (char*)spath, f->namlen);
#if NEW_ATTRIB_HANDLING
f->attributes[0] = (uint8) get_nw_attrib_dword(stb, voloptions);
#else
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
#endif
un_date_2_nw(stb->st_mtime, f->created.date,0); un_date_2_nw(stb->st_mtime, f->created.date,0);
un_time_2_nw(stb->st_mtime, f->created.time,0); un_time_2_nw(stb->st_mtime, f->created.time,0);
U32_TO_BE32(get_file_owner(stb), f->created.id); U32_TO_BE32(get_file_owner(stb), f->created.id);
@ -2205,11 +2322,11 @@ int nw_scan_a_directory(uint8 *rdata,
uint32 searchbeg) /* 32 bit */ uint32 searchbeg) /* 32 bit */
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dirhandle, data, len, 0); struct stat stbuff;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, len, 0);
XDPRINTF((5,0,"nw_scan_a_directory path:%s:, fn:%s:, completition:0x%x", XDPRINTF((5,0,"nw_scan_a_directory path:%s:, fn:%s:, completition:0x%x",
nwpath.path, nwpath.fn, completition)); nwpath.path, nwpath.fn, completition));
if (completition > -1) { if (completition > -1) {
struct stat stbuff;
int searchsequence = (searchbeg == MAX_U32) ? MAX_U16 : searchbeg; int searchsequence = (searchbeg == MAX_U32) ? MAX_U16 : searchbeg;
if (get_dir_entry(&nwpath, if (get_dir_entry(&nwpath,
&searchsequence, &searchsequence,
@ -2240,12 +2357,12 @@ int nw_scan_a_root_dir(uint8 *rdata,
int dirhandle) int dirhandle)
{ {
NW_PATH nwpath; NW_PATH nwpath;
struct stat stbuff;
uint8 data[2]; uint8 data[2];
int completition = conn_get_kpl_path(&nwpath, dirhandle, data, 0, 1); int completition = conn_get_kpl_path(&nwpath, &stbuff, dirhandle, data, 0, 1);
XDPRINTF((5,0,"nw_scan_a_root_directory_2 path:%s:, fn:%s:, completition:0x%x", XDPRINTF((5,0,"nw_scan_a_root_directory_2 path:%s:, fn:%s:, completition:0x%x",
nwpath.path, nwpath.fn, completition)); nwpath.path, nwpath.fn, completition));
if (completition > -1) { if (completition > -1) {
struct stat stbuff;
if (!s_stat(build_unix_name(&nwpath, 2), &stbuff, NULL)) { if (!s_stat(build_unix_name(&nwpath, 2), &stbuff, NULL)) {
NW_DOS_DIR_INFO *d=(NW_DOS_DIR_INFO*)rdata; NW_DOS_DIR_INFO *d=(NW_DOS_DIR_INFO*)rdata;
memset(rdata, 0, sizeof(NW_DOS_DIR_INFO)); memset(rdata, 0, sizeof(NW_DOS_DIR_INFO));
@ -2335,3 +2452,24 @@ void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp)
} }
int nw_add_trustee(int dir_handle, uint8 *data, int len,
uint32 id, int trustee, int extended)
/* extended 0=add trustee to dir, 1= add ext trustee to dirs and files */
{
char unname[256];
struct stat stbuff;
NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, &stbuff, dir_handle, data, len,
(extended) ? 0 : 1);
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 0));
if (s_stat(unname, &stbuff, NULL) ||
(!extended && !S_ISDIR(stbuff.st_mode)) ) {
completition = -0x9c;
} else {
completition=set_nw_trustee(stbuff.st_dev, stbuff.st_ino,
id, trustee);
}
return(completition);
}

View File

@ -1,4 +1,4 @@
/* connect.h 27-Nov-97 */ /* connect.h 01-Feb-98 */
#ifndef _CONNECT_H_ #ifndef _CONNECT_H_
#define _CONNECT_H_ #define _CONNECT_H_
@ -124,8 +124,8 @@ extern int nw_delete_datei(int dir_handle, uint8 *data, int len);
extern int nw_set_file_information(int dir_handle, uint8 *data, int len, extern int nw_set_file_information(int dir_handle, uint8 *data, int len,
int searchattrib, NW_FILE_INFO *f); int searchattrib, NW_FILE_INFO *f);
extern int nw_chmod_datei(int dir_handle, uint8 *data, int len, extern int nw_set_file_attributes(int dir_handle, uint8 *data, int len,
int attrib, int access); int attrib, int newattrib);
extern int mv_file(int qdirhandle, uint8 *q, int qlen, extern int mv_file(int qdirhandle, uint8 *q, int qlen,
int zdirhandle, uint8 *z, int zlen); int zdirhandle, uint8 *z, int zlen);
@ -153,30 +153,31 @@ extern int nw_find_dir_handle( int dir_handle,
int len); /* L„nge Pfad */ int len); /* L„nge Pfad */
extern int xinsert_new_dir(int volume, uint8 *path, extern int xinsert_new_dir(int volume, uint8 *path,
int inode, int drive, int is_temp, int task); int dev, int inode,
int drive, int is_temp, int task);
extern int nw_alloc_dir_handle( extern int nw_alloc_dir_handle(
int dir_handle, /* Suche ab Pfad dirhandle */ int dir_handle, /* directory handle */
uint8 *data, /* zus„tzl. Pfad */ uint8 *data, /* extra path */
int len, /* L„nge DATA */ int len, /* len of datat */
int driveletter, /* A .. Z normal */ int driveletter, /* A .. Z normal */
int is_temphandle, /* tempor„res Handle 1 */ int is_temphandle, /* temp Handle 1 */
/* spez. temp Handle 2 */ /* spez. temp Handle 2 */
int task); /* Prozess Task */ int task); /* Prozess Task */
extern int nw_open_dir_handle( int dir_handle, extern int nw_open_dir_handle( int dir_handle,
uint8 *data, /* zus„tzlicher Pfad */ uint8 *data, /* extra path */
int len, /* L„nge DATA */ int len, /* len data */
int *volume, /* Volume */ int *volume, /* Volume */
int *dir_id, /* „hnlich Filehandle */ int *dir_id, /* similar to filehandle*/
int *searchsequence); int *searchsequence);
extern int nw_free_dir_handle(int dir_handle, int task); extern int nw_free_dir_handle(int dir_handle, int task);
extern int alter_dir_handle(int targetdir, int volume, uint8 *path, extern int alter_dir_handle(int targetdir, int volume, uint8 *path,
int inode, int task); int dev, int inode, int task);
extern int nw_set_dir_handle(int targetdir, int dir_handle, extern int nw_set_dir_handle(int targetdir, int dir_handle,
uint8 *data, int len, int task); uint8 *data, int len, int task);
@ -187,7 +188,8 @@ extern int nw_get_vol_number(int dir_handle);
extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus); extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len,
int modus);
extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len, extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len,
uint8 *subnr, uint8 *subname, uint8 *subnr, uint8 *subname,
@ -211,8 +213,6 @@ extern int act_gid;
extern int act_obj_id; /* not login == 0 */ extern int act_obj_id; /* not login == 0 */
extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */ extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */
extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
uint8 *data, int len, int only_dir) ;
extern int conn_get_full_path(int dirhandle, uint8 *data, int len, extern int conn_get_full_path(int dirhandle, uint8 *data, int len,
uint8 *fullpath); uint8 *fullpath);
@ -248,11 +248,19 @@ extern int fn_dos_match(uint8 *s, uint8 *p, int options);
extern void un_date_2_nw(time_t time, uint8 *d, int high_low); extern void un_date_2_nw(time_t time, uint8 *d, int high_low);
extern time_t nw_2_un_time(uint8 *d, uint8 *t); extern time_t nw_2_un_time(uint8 *d, uint8 *t);
#if !NEW_ATTRIB_HANDLING
extern int un_nw_attrib(struct stat *stb, int attrib, int mode); extern int un_nw_attrib(struct stat *stb, int attrib, int mode);
#endif
extern int un_nw_rights(struct stat *stb); extern int un_nw_rights(struct stat *stb);
extern void un_time_2_nw(time_t time, uint8 *d, int high_low); extern void un_time_2_nw(time_t time, uint8 *d, int high_low);
extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp); extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp);
extern int nw_add_trustee(int dir_handle, uint8 *data, int len,
uint32 id, int trustee, int extended);
#endif #endif

View File

@ -24,8 +24,8 @@ If you have problems.
some short notes for problem- or bug-reports. some short notes for problem- or bug-reports.
--------------------------------------------- ---------------------------------------------
- report your running environment - report your running environment
full mars_nwe version, example: 0.99.pl0 full mars_nwe version, example: 0.99.pl5
linux-kernel, 2.0.29 linux-kernel, 2.0.32
exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. ) exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. )
changes you made into nwserv.conf(nw.ini), config.h. changes you made into nwserv.conf(nw.ini), config.h.
- if you send nwserv.conf, please remove the comments first. - if you send nwserv.conf, please remove the comments first.

View File

@ -392,4 +392,22 @@ Erste 'oeffentliche' Version
- Creat mode von Verzeichnissen erweitert. - Creat mode von Verzeichnissen erweitert.
- Verzeichnisse werden nicht mehr auf readonly gesetzt. - Verzeichnisse werden nicht mehr auf readonly gesetzt.
<----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- negotiate Buffersize von < 512 wird nun ignoriert. ( Hayo Schmidt )
- namspace.c:
- get_dbe_data_from_disk: Rechteproblem beim readlink beseitigt.
- max_dir_base_entries nun auch in conf file aenderbar (section 63)
- nw_search_file_dir so abgeaendert dass das Loeschen von Verzeichnissen
nun funktionieren sollte. Evtl. muss bei sehr grossen Verzeichnissen
max_dir_search_handles(section 80 in nwserv.conf) hochgesetzt werden.
<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- connect.c. un_nw_rights default rights now 0xff (pconsole needs TRUSTEE_O)
- nwattrib.c : set_nw_attrib_byte korrigiert.
- nwserv kann nun per externen Aufruf Interfaces anlegen und loeschen.
nwserv -a device frame net bzw. nwserv -d device frame.
- neuer Schalter nwserv -f. Force send rip sap.
- archive bit ist bei Dateien nun default gesetzt.
- archive bit wird nun bei Client Schreiboperationen gesetzt.
<----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -79,6 +79,9 @@ Andrew Sapozhnikov <sapa@hq.icb.chel.su>
added extend "Volume is home" feature. added extend "Volume is home" feature.
fixed "rename wildcard" bug. fixed "rename wildcard" bug.
Hayo Schmidt <100305.1424@compuserve.com>
added patch to let ATARI client work.
Gregory Steuck <greg@nsu.ru> Gregory Steuck <greg@nsu.ru>
testings and errorreports testings and errorreports

View File

@ -1,3 +1,11 @@
------08-Feb-98--- 0.99.pl6 ---------
- archive bit handling changed. (default set if file, unset if directory)
- section 5: deleting of ipx devices/routes changed.
- nwserv can be started to work similar to ipx_interface.
'nwserv -a device frame net' or 'nwserv -d device frame'
------01-Feb-98--- 0.99.pl5 ---------
- config.h: NEW_ATTRIB_HANDLING
- config.h: default HANDLE_ALL_SAP_TYPS is now set to 1.
------27-Nov-97--- 0.99.pl4 --------- ------27-Nov-97--- 0.99.pl4 ---------
- section 1: dir/file creat modes can now be set volume dependent. - section 1: dir/file creat modes can now be set volume dependent.
- section 9: dir creat mode may now be '-1' for use st_mode of - section 9: dir creat mode may now be '-1' for use st_mode of

View File

@ -1,16 +1,16 @@
Begin3 Begin3
Title: mars_nwe Title: mars_nwe
Version: 0.99.pl4 Version: 0.99.pl6
Entered-date: 28-Nov-97 Entered-date: 09-Feb-98
Description: Full netware-emulator (src), beta. Description: Full netware-emulator (src), beta.
Supports file-services, bindery-services, Supports file-services, bindery-services,
printing-services, routing-services. printing-services, routing-services.
Keywords: novell, netware, server, ipx, ncp, tli Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@compu-art.de (Martin Stover) Author: mstover@compu-art.de (Martin Stover)
Maintained-by: mstover@compu-art.de (Martin Stover) Maintained-by: mstover@compu-art.de (Martin Stover)
Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl4.tgz Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl6.tgz
250 kB 250 kB
Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl4.tgz Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl6.tgz
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
Copying-policy: GNU Copying-policy: GNU
End End

View File

@ -246,12 +246,13 @@ static int add_special_net(int special,
#define add_internal_net(netnum, node) \ #define add_internal_net(netnum, node) \
add_special_net(IPX_INTERNAL, NULL, 0, (netnum), (node)) add_special_net(IPX_INTERNAL, NULL, 0, (netnum), (node))
#define add_device_net(devname, frame, netnum) \
add_special_net(IPX_SPECIAL_NONE, (devname), (frame), (netnum), 0)
#define add_primary_net(devname, frame, netnum) \ #define add_primary_net(devname, frame, netnum) \
add_special_net(IPX_PRIMARY, (devname), (frame), (netnum), 0) add_special_net(IPX_PRIMARY, (devname), (frame), (netnum), 0)
int add_device_net(char *devname, int frame, uint32 netnum)
{
return(add_special_net(IPX_SPECIAL_NONE, (devname), (frame), (netnum), 0));
}
int get_frame_name(uint8 *framename, int frame) int get_frame_name(uint8 *framename, int frame)
{ {
@ -340,7 +341,7 @@ void exit_ipx(int flags)
ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces); ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces);
close(sock); close(sock);
} }
if (have_ipx_started && !(flags&1)) { if (have_ipx_started && flags&4) {
del_all_interfaces_nets(); del_all_interfaces_nets();
} }
} }

View File

@ -26,6 +26,7 @@ extern int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
int *flags, uint8 *name); int *flags, uint8 *name);
extern int get_interface_frame_name(char *name, uint32 net); extern int get_interface_frame_name(char *name, uint32 net);
extern int add_device_net(char *devname, int frame, uint32 netnum);
extern int get_frame_name(uint8 *framename, int frame); extern int get_frame_name(uint8 *framename, int frame);
extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags); extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags);

View File

@ -1,4 +1,4 @@
This is an important kernel ipx patch for all known kernels. This is an important kernel ipx patch for all known kernels prior 2.0.32
In linux/net/ipx/af_ipx.c routine ipx_create one line is missing. In linux/net/ipx/af_ipx.c routine ipx_create one line is missing.

View File

@ -1,4 +1,4 @@
/* config.h: 10-Nov-97 */ /* config.h: 04-Feb-98 */
/* some of this config is needed by make, others by cc */ /* some of this config is needed by make, others by cc */
#define DO_DEBUG 1 /* compile in debug code */ #define DO_DEBUG 1 /* compile in debug code */
@ -33,19 +33,20 @@
/* connections handled by mars_nwe */ /* connections handled by mars_nwe */
/* !! NOTE !! */ /* !! NOTE !! */
/* If set > 255 some NCP calls will probably not work, try it with caution */ /* If set > 255 some NCP calls will probably not work, try it with caution */
/* and you should apply examples/kpatch2.0.29 */ /* and you should apply examples/kpatch2.0.29 to kernels prior 2.0.32 */
#define IPX_DATA_GR_546 1 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */ #define IPX_DATA_GR_546 2 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */
/* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */ /* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */
/* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */ /* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */
/* 3 = max. IPX packets = 4130 +30 Byte (4096 Byte RWBuff) */ /* 3 = max. IPX packets = 4130 +30 Byte (4096 Byte RWBuff) */
#define ENABLE_BURSTMODE 0 /* 0 = disable burstmode, 1 = enable burstmode */ #define ENABLE_BURSTMODE 0 /* 0 = disable burstmode, 1 = enable burstmode */
/* in 0.98.pl11 still NOT working !! */ /* still NOT working correct !!!!! */
/* to get Burstmode really enabled, section '6' in conf-file */ /* to get Burstmode really enabled, section '6' in conf-file */
/* must be set to a value > 1 (3.12 Server) */ /* must be set to a value > 1 (3.12 Server) */
/* and kernel-patch examples/kpatch2.0.29 should be used */ /* and kernel-patch examples/kpatch2.0.29 should be used for */
/* kernels prior 2.0.32 */
#define USE_MMAP 1 /* use mmap systen call, not always best choice */ #define USE_MMAP 1 /* use mmap systen call, not always best choice */
@ -69,15 +70,17 @@
/* entry '6' in ini file should be set*/ /* entry '6' in ini file should be set*/
/* to > '0', too. */ /* to > '0', too. */
/* <--------------------------------------------------------------------> */ /* <--------------------------------------------------------------------> */
#define HANDLE_ALL_SAP_TYPS 0 /* if set to 0 only SAP-Typ 4 Servers */ #define HANDLE_ALL_SAP_TYPS 1 /* if set to 0 only SAP-Typ 4 Servers */
/* will be put into routing table and */ /* will be put into routing table and */
/* if set to 1 all SAP Typs will be */ /* if set to 1 all SAP Typs will be */
/* used. */ /* used. */
#define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */ #define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */
/* main idea from Victor Khimenko */ /* main idea from Victor Khimenko */
/* in 0.99.pl0 still NOT working !! */ /* in 0.99.pl0 still NOT working !! */
#define NEW_ATTRIB_HANDLING 0 /* better (if working ;)) attrib handling */
/* <--------------- next is for linux only ----------------------------> */ /* <--------------- next is for linux only ----------------------------> */
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */

View File

@ -2,8 +2,9 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator # This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux. # for Linux.
# #
# last changed: 27-Nov-97 # last changed: 08-Feb-98
# #
# !! section 5 : deleting of ipx devices/routes changed in 0.99.pl6 !!
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !! # !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
# #
# since version 0.98.pl11: # since version 0.98.pl11:
@ -285,22 +286,31 @@
# 4 0x0 ippp0 AUTO 7 # auto ippp0 (isdn ppp) interface. # 4 0x0 ippp0 AUTO 7 # auto ippp0 (isdn ppp) interface.
# 4 0x0 ppp0 AUTO 7 # auto detection of ppp0 interface. # 4 0x0 ppp0 AUTO 7 # auto detection of ppp0 interface.
4 0x22 eth0 ethernet_ii 1 4 0x22 eth0 ethernet_ii 1
4 0x0 * AUTO 1 4 0x0 * AUTO 1
# Section 5: special device flags # Section 5: special device flags
# ========================================================================= # =========================================================================
# Flags # Flags
# 0x1 do not remove routes and ipx-devices # 0x1 do not remove by nwserv/nwrouted added routes and ipx-devices
# beyond the lifetime of the server or router. # beyond the lifetime of the server or router.
# If this flag is not set then all ipx-devices/routes # If this flag is not set then all by nwserv/nwrouted added
# will be deleted when nwserv/nwrouted ends (default). # ipx-devices/routes will be deleted when
# nwserv/nwrouted ends (default).
# #
# 0x2 Switch on automatic kernel creation of ipx-interfaces. # 0x2 Switch on automatic kernel creation of ipx-interfaces.
# The automatic kernel creating of ipx-devices sometimes # The automatic kernel creating of ipx-devices sometimes
# make trouble (Win95). It should only be used in the # make trouble (Win95). It should only be used in the
# beginning or for testing. # beginning or for testing.
# #
# 0x4 do remove ALL routes and ipx-devices
# beyond the lifetime of the server or router.
# If this flag is set then all ipx-devices/routes
# will be deleted when nwserv/nwrouted ends.
# This was the default prior mars_nwe 0.99.pl6 !
#
#
# other flags may follow. # other flags may follow.
# value will be interpreted as hex value. # value will be interpreted as hex value.
@ -673,12 +683,14 @@
40 /var/spool/nwserv/.volcache 40 /var/spool/nwserv/.volcache
# 41 = path for share/lock files # 41 = path for share/lock files
41 /var/spool/nwserv/.locks 41 /var/spool/nwserv/.locks
# 42 = path for spool dir # 42 = path for spool dir, e.g. internal print queue handling
42 /var/spool/nwserv 42 /var/spool/nwserv
# #
# #
# 45 = path for bindery file's # 45 = path for bindery file's
45 /etc 45 /etc
# 46 = path for attribute handling and later trustees
46 /var/lib/nwserv/attrib
# ========================================================================= # =========================================================================
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru> # Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
# Tables for DOS->Unix names translation & upper/lowercase translations # Tables for DOS->Unix names translation & upper/lowercase translations
@ -701,9 +713,10 @@
# more information in config.h # more information in config.h
# 60 10 # MAX_CONNECTIONS # 60 10 # MAX_CONNECTIONS
# 61 10 # MAX_NW_VOLS # 61 10 # MAX_NW_VOLS
# 63 50 # MAX_DIR_BASE_ENTRIES
# 68 1 # USE_MMAP (use mmap=1, no mmap=0) # 68 1 # USE_MMAP (use mmap=1, no mmap=0)
# 69 0 # HANDLE_ALL_SAP_TYPS (all sap typs=1, only typ 4=0) # 69 1 # HANDLE_ALL_SAP_TYPS (all sap typs=1, only typ 4=0)
# 70 0x44444444 # NETWORK_SERIAL_NMBR (4 byte) # 70 0x44444444 # NETWORK_SERIAL_NMBR (4 byte)
# 71 0x2222 # NETWORK_APPL_NMBR (2 byte) # 71 0x2222 # NETWORK_APPL_NMBR (2 byte)
@ -713,6 +726,8 @@
# You usally don't want to change anything below this line # You usally don't want to change anything below this line
# -------------------------------------------------------- # --------------------------------------------------------
# Sections 80-99: some more constants
# 80 50 # max_dir_search_handles (namspace.c)
# Sections 100-106: amount of debug-information # Sections 100-106: amount of debug-information
# #

View File

@ -1,5 +1,5 @@
#if 0 #if 0
#makefile.unx 10-Nov-97 #makefile.unx 04-Feb-98
#endif #endif
VPATH=$(V_VPATH) VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0 V_H=0
V_L=99 V_L=99
P_L=4 P_L=6
#define D_P_L 1 #define D_P_L 1
DISTRIB=mars_nwe DISTRIB=mars_nwe
@ -116,7 +116,8 @@ PROGS=$(INSTALLPROGS) $(PROG8)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwattrib$(O)
OBJ4= $(OBJ1) OBJ4= $(OBJ1)
OBJ5= $(OBJ1) OBJ5= $(OBJ1)
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O)
@ -127,6 +128,7 @@ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
$(EMUTLIOBJ1) $(NWROUTE_O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \ nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwattrib$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \ nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \
$(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \
$(PROG7)$(O) $(PROG8)$(O) $(PROG7)$(O) $(PROG8)$(O)
@ -134,7 +136,7 @@ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \
unxfile$(O) unxfile$(O)
HOBJ6= $(PROG6)$(O) sema$(O) HOBJ6= $(PROG6)$(O) sema$(O)
#if 0 #if 0
#$(PROG1): $(PROG1)$(O) $(OBJ1) #$(PROG1): $(PROG1)$(O) $(OBJ1)
@ -192,7 +194,7 @@ n_install:
@-if [ -r /sbin/nwserv ] && [ -r /usr/sbin/nwserv ] ; then \ @-if [ -r /sbin/nwserv ] && [ -r /usr/sbin/nwserv ] ; then \
echo "remove old version in /sbin ?" ; \ echo "remove old version in /sbin ?" ; \
(cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \ (cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \
fi ; fi ;
@cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \ @cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \
echo ""; \ echo ""; \
echo "********************************************************"; \ echo "********************************************************"; \
@ -219,8 +221,7 @@ echo "********************************************************"; \
cd $(OBJDIR) ) cd $(OBJDIR) )
n_reboot: n_install n_reboot: n_install
-nwserv -k -(nwserv -k ; nwserv)&
nwserv
clean_d: clean_d:
cd $(VPATH) && (\ cd $(VPATH) && (\
@ -230,7 +231,9 @@ clean_d:
n_clean: n_clean:
rm -f *.o rm -f *.o
cd $(VPATH) && (rm -f $(PROGS) $(PROG7); cd $(OBJDIR) ) cd $(VPATH) && (rm -f $(PROGS) $(PROG7) \
; rm -rf $(OBJDIR)/$(VPATH)/$(DISTRIB) \
; cd $(OBJDIR) )
n_distclean: n_clean clean_d n_distclean: n_clean clean_d
cd $(VPATH) && (rm -f *.dir *.pag; cd $(OBJDIR)) cd $(VPATH) && (rm -f *.dir *.pag; cd $(OBJDIR))

View File

@ -1,9 +1,9 @@
/* namspace.c 12-Aug-97 : NameSpace Services, mars_nwe */ /* namspace.c 01-Feb-98 : NameSpace Services, mars_nwe */
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */
/* Its still dirty, but it should work fairly well */ /* Its still dirty, but it should work fairly well */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -30,6 +30,7 @@
#include "nwfname.h" #include "nwfname.h"
#include "nwvolume.h" #include "nwvolume.h"
#include "connect.h" #include "connect.h"
#include "nwattrib.h"
#include "nwconn.h" #include "nwconn.h"
#include "nwfile.h" #include "nwfile.h"
#include "unxfile.h" #include "unxfile.h"
@ -40,13 +41,6 @@
#define NW_PATH /* */ #define NW_PATH /* */
#if 0
/* for tests only */
# undef MAX_DIR_BASE_ENTRIES
# define MAX_DIR_BASE_ENTRIES 10
#endif
typedef struct { typedef struct {
int volume; /* Volume Number */ int volume; /* Volume Number */
int has_wild; /* fn has wildcards */ int has_wild; /* fn has wildcards */
@ -71,27 +65,24 @@ typedef struct {
N_NW_PATH nwpath; N_NW_PATH nwpath;
} DIR_BASE_ENTRY; } DIR_BASE_ENTRY;
static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES]; static DIR_BASE_ENTRY **dir_base=NULL;
static int anz_dbe = 0; static int anz_dbe = 0;
static int max_dir_base_entries=0;
#define MAX_DIR_SEARCH_HANDLES 10
#if MAX_DIR_SEARCH_HANDLES > 255
# undef MAX_DIR_SEARCH_HANDLES
# define MAX_DIR_SEARCH_HANDLES 255
#endif
typedef struct { typedef struct {
int dev; /* from searchdir */
ino_t inode; /* from searchdir */
int idle; int idle;
off_t dirpos; /* last readdirpos */ off_t dirpos; /* last readdirpos */
ino_t found_inode; /* last found inode at readdirpos */ ino_t found_inode; /* last found inode at readdirpos */
int lastsequence; /* last sequence */ int lastsequence; /* last sequence */
} DIR_SEARCH_HANDLE; } DIR_SEARCH_HANDLE;
static DIR_SEARCH_HANDLE *dir_search_handles[MAX_DIR_SEARCH_HANDLES]; static DIR_SEARCH_HANDLE **dir_search_handles=NULL;
static int count_dsh = 0; static int count_dsh = 0;
static int max_dir_search_handles=0;
static uint32 new_search_handle(void) static uint32 new_search_handle(int dev, ino_t inode)
{ {
int k=count_dsh; int k=count_dsh;
int foundfree=-1; int foundfree=-1;
@ -99,10 +90,17 @@ static uint32 new_search_handle(void)
while (k--) { while (k--) {
if (!dir_search_handles[k]) { if (!dir_search_handles[k]) {
foundfree=k; foundfree=k;
break; } else {
} else dir_search_handles[k]->idle++; if (dir_search_handles[k]->idle < MAX_I32)
dir_search_handles[k]->idle++;
else {
xfree(dir_search_handles[k]);
if (foundfree < 0 && k+1==count_dsh) count_dsh--;
else foundfree=k;
}
}
} }
if (foundfree < 0 && count_dsh < MAX_DIR_SEARCH_HANDLES) if (foundfree < 0 && count_dsh < max_dir_search_handles)
foundfree=count_dsh++; foundfree=count_dsh++;
if (foundfree < 0) { if (foundfree < 0) {
int idle=-1; int idle=-1;
@ -118,19 +116,19 @@ static uint32 new_search_handle(void)
} }
d=dir_search_handles[foundfree]; d=dir_search_handles[foundfree];
memset(d, 0, sizeof(DIR_SEARCH_HANDLE)); memset(d, 0, sizeof(DIR_SEARCH_HANDLE));
d->dev = dev;
d->inode = inode;
return((uint32) foundfree); return((uint32) foundfree);
} }
#if 0 /* probably never needed */ static void free_search_handles(void)
static void free_search_handle(uint32 handle)
{ {
if (handle < count_dsh) { while (count_dsh--) {
xfree(dir_search_handles[handle]); xfree(dir_search_handles[count_dsh]);
if (count_dsh == handle+1)
--count_dsh;
} }
count_dsh=0;
xfree(dir_search_handles);
} }
#endif
static void init_nwpath(N_NW_PATH *nwpath, int namespace) static void init_nwpath(N_NW_PATH *nwpath, int namespace)
{ {
@ -338,8 +336,7 @@ static void del_dbe_from_disk(DIR_BASE_ENTRY *dbe)
static int get_dbe_data_from_disk(int volume, static int get_dbe_data_from_disk(int volume,
int dev, int ino, uint8 *path, int dev, ino_t inode, uint8 *path)
struct stat *statb)
/* returns 0 if all ok */ /* returns 0 if all ok */
{ {
char buf[255]; char buf[255];
@ -349,9 +346,11 @@ static int get_dbe_data_from_disk(int volume,
#if 0 #if 0
int voloptions=get_volume_options(volume); int voloptions=get_volume_options(volume);
#endif #endif
if (nw_get_volume_name(volume, volname) < 1) if (nw_get_volume_name(volume, volname) < 1) {
XDPRINTF((1, 0, "get_dbe_d_f_d: wrong volume=%d", volume));
return (-1); return (-1);
U32_TO_BE32(ino, inode_uc); }
U32_TO_BE32(inode, inode_uc);
sprintf(buf, "%s/%s/%x/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname, sprintf(buf, "%s/%s/%x/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname,
#if 0 #if 0
(voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0, (voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0,
@ -363,12 +362,18 @@ static int get_dbe_data_from_disk(int volume,
(int) inode_uc[1], (int) inode_uc[1],
(int) inode_uc[2], (int) inode_uc[2],
(int) inode_uc[3]); (int) inode_uc[3]);
seteuid(0);
l=readlink(buf, path, 511); l=readlink(buf, path, 511);
reseteuid();
if (l > 0) { if (l > 0) {
path[l]='\0'; path[l]='\0';
return(0); return(0);
} else {
errorp(0, "get_dbe_d_f_d", "readlink of `%s`=%d", buf, l);
return(-1);
} }
return(-1);
} }
static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) static DIR_BASE_ENTRY *allocate_dbe_p(int namespace)
@ -391,7 +396,7 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace)
} }
if (j == anz_dbe) { if (j == anz_dbe) {
if (anz_dbe == MAX_DIR_BASE_ENTRIES) { if (anz_dbe == max_dir_base_entries) {
if (to_use_free > -1) { if (to_use_free > -1) {
j = to_use_free; j = to_use_free;
} else if (to_use_file > -1) { } else if (to_use_file > -1) {
@ -416,6 +421,24 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace)
return(dbe); return(dbe);
} }
static void free_dir_bases(void)
/* free's all dir_bases */
{
if (dir_base) {
while (anz_dbe--) {
if (dir_base[anz_dbe]) {
if (S_ISDIR(dir_base[anz_dbe]->nwpath.statb.st_mode)
|| (entry8_flags & 0x20) ) {
put_dbe_to_disk(dir_base[anz_dbe]);
}
xfree(dir_base[anz_dbe]);
}
}
anz_dbe=0;
xfree(dir_base);
}
}
static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe) static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe)
{ {
if (NULL != dbe && NULL != *dbe) { if (NULL != dbe && NULL != *dbe) {
@ -443,6 +466,25 @@ static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe)
return(dbase); return(dbase);
} }
static void rmdir_from_structures(DIR_BASE_ENTRY *dbe)
/* is called after directory is deleted from disk, frees some structures */
{
int k=count_dsh;
int dev = dbe->nwpath.statb.st_dev;
ino_t inode = dbe->nwpath.statb.st_ino;
free_nw_ext_inode(dev, inode);
while (k--) {
DIR_SEARCH_HANDLE *dsh=dir_search_handles[k];
if (dsh && dsh->inode == inode && dsh->dev == dev) {
xfree(dir_search_handles[k]);
if (k+1 == count_dsh)
count_dsh--;
}
}
del_dbe_from_disk(dbe);
free_dbe_p(dbe);
}
static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes)
/* returns size of path components in bytes */ /* returns size of path components in bytes */
@ -683,23 +725,27 @@ static int find_base_entry(int volume, uint32 basehandle)
} }
} }
} }
/* now we test whether it is the root of volume */
if (0 < ino) { if (0 < ino) {
struct stat statb; struct stat statb;
uint8 path[512]; uint8 path[512];
/* now we test whether it is the root of volume */
if (ino == get_volume_inode(volume, &statb)) { if (ino == get_volume_inode(volume, &statb)) {
/* its the handle of the volumes root */ /* its the handle of the volumes root */
return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb)); return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb));
} }
if (!get_dbe_data_from_disk(volume, dnm.dev, ino, path, &statb)) { /* now we try it from disk */
if (!get_dbe_data_from_disk(volume, dnm.dev, ino, path)) {
/* we found it on disk */ /* we found it on disk */
return(add_dbe_entry(dnm.namespace, volume, basehandle, path, NULL)); return(add_dbe_entry(dnm.namespace, volume, basehandle, path, NULL));
} }
} }
XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x", volume, basehandle));
XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x, dev=0x%x, inode=%d",
volume, basehandle, dnm.dev, ino));
return(-0x9b); return(-0x9b);
} }
@ -862,7 +908,7 @@ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname)
#if 0 #if 0
typedef struct { typedef struct {
int anz; int anz;
DIR_BASE_ENTRY *ee[MAX_DIR_BASE_ENTRIES]; DIR_BASE_ENTRY **ee;
} BASE_COMPONENTS; } BASE_COMPONENTS;
static BASE_COMPONENTS *get_path_components(DIR_BASE_ENTRY *dbe) static BASE_COMPONENTS *get_path_components(DIR_BASE_ENTRY *dbe)
@ -978,10 +1024,14 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe,
p += 4; p += 4;
if (infomask & INFO_MSK_ATTRIBUTE_INFO) { if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
#if NEW_ATTRIB_HANDLING
uint32 attrib = get_nw_attrib_dword(stb, voloptions);
#else
uint32 attrib = ( (!S_ISDIR(stb->st_mode)) uint32 attrib = ( (!S_ISDIR(stb->st_mode))
&& (voloptions & VOL_OPTION_IS_PIPE) ) && (voloptions & VOL_OPTION_IS_PIPE) )
? (uint32) FILE_ATTR_SHARE|FILE_ATTR_A ? (uint32) FILE_ATTR_SHARE|FILE_ATTR_A
: (uint32) un_nw_attrib(stb, 0, 0); : (uint32) un_nw_attrib(stb, 0, 0);
#endif
U32_TO_32(attrib, p); U32_TO_32(attrib, p);
p += 4; p += 4;
U16_TO_16((uint16)(attrib & 0xFFFF), p); U16_TO_16((uint16)(attrib & 0xFFFF), p);
@ -1318,7 +1368,10 @@ int nw_search_file_dir(int namespace, int datastream,
int max_counts = *count; int max_counts = *count;
#endif #endif
int result = find_base_entry(volume, basehandle); int result = find_base_entry(volume, basehandle);
DIR_BASE_ENTRY *dest_dbe=NULL; DIR_BASE_ENTRY *dest_dbe=NULL;
DIR_SEARCH_HANDLE *dsh=NULL;
DIR_BASE_ENTRY *dbe=NULL;
int sequence; int sequence;
*perhaps_more = 0; *perhaps_more = 0;
*count = 0; *count = 0;
@ -1326,27 +1379,40 @@ int nw_search_file_dir(int namespace, int datastream,
MDEBUG(D_FN_SEARCH, { MDEBUG(D_FN_SEARCH, {
char fname[300]; char fname[300];
strmaxcpy(fname, path, min(sizeof(fname)-1, len)); strmaxcpy(fname, path, min(sizeof(fname)-1, len));
xdprintf(1,0,"nwsfd:seqence=%d, base=%d, attrib=0x%x, fn=`%s`", xdprintf(1,0,"nwsfd:sequence=%d,%d, base=%d, attrib=0x%x, fn=`%s`",
*psequence, basehandle, searchattrib, fname); *psequence & 0xff, *psequence >> 8, basehandle,
searchattrib, fname);
}) })
if (len > 255) result=-0x9c; /* we say wrong path here */ if (len > 255) result=-0x9c; /* we say wrong path here */
else if (result > -1) { else if (result > -1) {
dbe=dir_base[result];
if (*psequence == MAX_U32) { if (*psequence == MAX_U32) {
*psequence=new_search_handle(); *psequence=new_search_handle(dbe->nwpath.statb.st_dev,
dbe->nwpath.statb.st_ino);
MDEBUG(D_FN_SEARCH, { MDEBUG(D_FN_SEARCH, {
xdprintf(1,0,"nwsfd:got new search seqence=%d", *psequence); xdprintf(1,0,"nwsfd:got new search seqence=%d", *psequence);
}) })
}
sequence = *psequence >> 8;
*psequence &= 0xff;
if (*psequence < count_dsh) {
dsh=dir_search_handles[*psequence];
if (dsh && (dbe->nwpath.statb.st_dev != dsh->dev
|| dbe->nwpath.statb.st_ino != dsh->inode))
dsh=NULL;
}
if (!dsh) {
*psequence=new_search_handle(dbe->nwpath.statb.st_dev,
dbe->nwpath.statb.st_ino);
*psequence &= 0xff;
dsh=dir_search_handles[*psequence];
} }
} }
sequence = *psequence >> 8; if (NULL != dsh) {
*psequence &= 0xff;
if (result > -1 && *psequence < count_dsh) {
DIR_SEARCH_HANDLE *dsh=dir_search_handles[*psequence];
DIR_BASE_ENTRY *dbe=dir_base[result];
DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT));
ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258); ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258);
@ -1364,7 +1430,7 @@ int nw_search_file_dir(int namespace, int datastream,
*(++(ds->kpath)) = '\0'; *(++(ds->kpath)) = '\0';
dbe->locked++; /* lock dbe */ dbe->locked++; /* lock dbe */
dsh->idle=0; /* touch dsh */ dsh->idle=0; /* touch dsh */
while (len--) { while (len--) {
uint8 c=*path++; uint8 c=*path++;
@ -1480,11 +1546,12 @@ int nw_search_file_dir(int namespace, int datastream,
dsh->lastsequence++; dsh->lastsequence++;
} /* while */ } /* while */
*psequence |= (dsh->lastsequence << 8); *psequence |= (dsh->lastsequence << 8);
if (!*perhaps_more) dsh->idle=MAX_I32-4;
XDPRINTF((5, 0, "more=%d, sequence = 0x%x, file=%s,next=%s", XDPRINTF((5, 0, "more=%d, sequence = 0x%x, file=%s,next=%s",
*perhaps_more, *psequence, dest_dbe->nwpath.path, *perhaps_more, *psequence, dest_dbe->nwpath.path,
dirbuff?dirbuff->d_name:"")); dirbuff?dirbuff->d_name:""));
} else { } else {
dsh->idle = 1000; dsh->idle = MAX_I32-2;
dsh->dirpos = (off_t)0; dsh->dirpos = (off_t)0;
result=-0xff; /* no files matching */ result=-0xff; /* no files matching */
XDPRINTF((5, 0, "no files matching")); XDPRINTF((5, 0, "no files matching"));
@ -1679,17 +1746,25 @@ static int delete_file_dir(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs)
uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2);
int result; int result;
if (S_ISDIR(dbe->nwpath.statb.st_mode)) { if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
result = rmdir(unname); int voloptions = get_volume_options(dbe->nwpath.volume);
if (result < 0) { /* directory */
switch (errno) { if (get_nw_attrib_dword(&dbe->nwpath.statb, voloptions) & FILE_ATTR_R)
case EEXIST: result=-0xa0; /* dir not empty */ result = -0x8a; /* don't delete 'readonly' */
default: result=-0x8a; /* No privilegs */ else {
result = rmdir(unname);
if (result < 0) {
switch (errno) {
case EEXIST: result=-0xa0; /* dir not empty */
default: result=-0x8a; /* No privilegs */
}
} }
} else { }
if (result>-1) {
rmdir_from_structures(dbe);
result = 0; result = 0;
free_dbe_p(dbe);
} }
} else { } else {
/* file */
if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname))) if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname)))
free_dbe_p(dbe); free_dbe_p(dbe);
} }
@ -1721,7 +1796,8 @@ static int nw_alloc_short_dir_handle(int namespace, int hmode,
DIR_BASE_ENTRY *dbe=dir_base[result]; DIR_BASE_ENTRY *dbe=dir_base[result];
if (S_ISDIR(dbe->nwpath.statb.st_mode)) { if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path, result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path,
dbe->nwpath.statb.st_ino, 300, hmode, task); dbe->nwpath.statb.st_dev, dbe->nwpath.statb.st_ino,
300, hmode, task);
*volume=dbe->nwpath.volume; *volume=dbe->nwpath.volume;
} else result=-0xff; } else result=-0xff;
} }
@ -1737,7 +1813,7 @@ static int nw_set_short_dir_handle(int namespace, int desthandle,
if (S_ISDIR(dbe->nwpath.statb.st_mode)) { if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
result=alter_dir_handle(desthandle, result=alter_dir_handle(desthandle,
dbe->nwpath.volume, dbe->nwpath.path, dbe->nwpath.volume, dbe->nwpath.path,
dbe->nwpath.statb.st_ino, task); dbe->nwpath.statb.st_dev, dbe->nwpath.statb.st_ino, task);
} else result=-0x9c; /* wrong path */ } else result=-0x9c; /* wrong path */
} }
return((result > 0) ? 0 : result); return((result > 0) ? 0 : result);
@ -2405,4 +2481,22 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task)
} /* switch */ } /* switch */
return(result); return(result);
} }
void exit_name_space_module(void)
{
free_dir_bases();
free_search_handles();
}
void init_name_space_module(int max_baseh, int max_searchh)
{
exit_name_space_module();
max_dir_base_entries=(max_baseh < 5) ? MAX_DIR_BASE_ENTRIES : max_baseh;
dir_base=(DIR_BASE_ENTRY **)xcmalloc(
sizeof(DIR_BASE_ENTRY*) * max_dir_base_entries);
max_dir_search_handles=(max_searchh < 10 || max_searchh > 255) ? 50 : max_searchh;
dir_search_handles=(DIR_SEARCH_HANDLE **)xcmalloc(
sizeof(DIR_SEARCH_HANDLE*) * max_dir_search_handles);
}
#endif #endif

View File

@ -1,6 +1,6 @@
/* namspace.h 01-Aug-97 : NameSpace Services, mars_nwe */ /* namspace.h 01-Feb-98 : NameSpace Services, mars_nwe */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -112,6 +112,9 @@ extern int fill_namespace_buffer(int volume, uint8 *rdata);
extern int get_namespace_dir_entry(int volume, uint32 basehandle, extern int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata); int namspace, uint8 *rdata);
extern void exit_name_space_module(void);
extern void init_name_space_module(int max_baseh, int max_searchh);
#endif #endif
#endif #endif

10
net.h
View File

@ -123,6 +123,7 @@ extern int errno;
#define MAX_U32 ((uint32)0xffffffffL) #define MAX_U32 ((uint32)0xffffffffL)
#define MAX_U16 ((uint16)0xffff) #define MAX_U16 ((uint16)0xffff)
#define MAX_I32 0x7fffffff
/* ===================> config.h <======================= */ /* ===================> config.h <======================= */
#ifdef CALL_NWCONN_OVER_SOCKET #ifdef CALL_NWCONN_OVER_SOCKET
@ -202,7 +203,7 @@ extern int errno;
#endif #endif
#ifndef IPX_DATA_GR_546 #ifndef IPX_DATA_GR_546
# define IPX_DATA_GR_546 1 # define IPX_DATA_GR_546 2
#endif #endif
#ifndef USE_MMAP #ifndef USE_MMAP
@ -222,7 +223,7 @@ extern int errno;
#endif #endif
#ifndef HANDLE_ALL_SAP_TYPS #ifndef HANDLE_ALL_SAP_TYPS
# define HANDLE_ALL_SAP_TYPS 0 # define HANDLE_ALL_SAP_TYPS 1
#endif #endif
#if IPX_DATA_GR_546 #if IPX_DATA_GR_546
@ -257,6 +258,11 @@ extern int errno;
# define DO_TESTING 0 # define DO_TESTING 0
#endif #endif
#ifndef NEW_ATTRIB_HANDLING
# define NEW_ATTRIB_HANDLING 1
#endif
#ifdef LINUX #ifdef LINUX
# ifndef QUOTA_SUPPORT # ifndef QUOTA_SUPPORT
# define QUOTA_SUPPORT 0 # define QUOTA_SUPPORT 0

329
nwattrib.c Normal file
View File

@ -0,0 +1,329 @@
/* nwattrib.c 09-Feb-98 */
/* (C)opyright (C) 1998 Martin Stover, Marburg, Germany
*
* 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"
#include <dirent.h>
#include "unxfile.h"
#include "nwvolume.h"
#include "connect.h"
#include "nwattrib.h"
static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib)
{
char buf[255];
char battrib[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
l=sprintf(buf, "%s/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2]);
seteuid(0);
unx_xmkdir(buf, 0755);
sprintf(buf+l, "/%x", (int) buf_uc[3]);
unlink(buf);
l=sprintf(battrib, "%08x", (unsigned int) attrib);
symlink(battrib, buf);
reseteuid();
}
static void free_attr_from_disk(int dev, ino_t inode)
{
char buf[255];
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unlink(buf);
reseteuid();
}
static int get_attr_from_disk(int dev, ino_t inode, uint32 *attrib)
/* returns 0 if all ok */
{
char buf[255];
char battrib[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
l=readlink(buf, battrib, 224);
reseteuid();
if (l > 0) {
unsigned int uattrib=0;
battrib[l]='\0';
if (1 == sscanf(battrib, "%x", &uattrib)) {
*attrib = uattrib;
return(0);
}
}
*attrib=0;
return(-1);
}
uint32 get_nw_attrib_dword(struct stat *stb, int voloptions)
/* returns full attrib_dword */
{
uint32 attrib=0;
int is_dir=S_ISDIR(stb->st_mode);
if (!is_dir && (voloptions & VOL_OPTION_IS_PIPE))
return(FILE_ATTR_SHARE|FILE_ATTR_A);
if (voloptions & VOL_OPTION_READONLY)
return((is_dir)?FILE_ATTR_DIR|FILE_ATTR_R:FILE_ATTR_R);
if (!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) {
if (is_dir) attrib |= FILE_ATTR_DIR;
else attrib &= (~FILE_ATTR_DIR);
} else {
if (is_dir)
attrib = FILE_ATTR_DIR;
else
attrib = FILE_ATTR_A; /* default archive flag */
}
if (act_uid) {
/* if not root */
int acc=get_real_access(stb);
if (!(acc & W_OK)) {
attrib |= FILE_ATTR_R; /* RO */
}
if (!(acc & R_OK)) {
attrib |= FILE_ATTR_H; /* We say hidden here */
}
}
return(attrib);
}
int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib)
{
int is_dir=S_ISDIR(stb->st_mode);
if (voloptions & VOL_OPTION_READONLY)
return(-0x8c); /* no modify rights */
if (voloptions & VOL_OPTION_IS_PIPE)
return(0);
if (!(get_real_access(stb) & W_OK))
return(-0x8c); /* no modify rights */
if (is_dir) attrib |= 0x10;
else attrib &= ~0x10;
put_attr_to_disk(stb->st_dev, stb->st_ino, attrib);
return(0);
}
int set_nw_attrib_byte(struct stat *stb, int voloptions, int battrib)
{
int is_dir=S_ISDIR(stb->st_mode);
uint32 attrib,oldattrib;
if (voloptions & VOL_OPTION_READONLY)
return(-0x8c); /* no modify rights */
if (voloptions & VOL_OPTION_IS_PIPE)
return(0);
if (!(get_real_access(stb) & W_OK))
return(-0x8c); /* no modify rights */
oldattrib=get_nw_attrib_dword(stb, voloptions);
attrib = (oldattrib & ~0xff);
attrib |= battrib;
if (is_dir) attrib |= 0x10;
else attrib &= ~0x10;
if (attrib != oldattrib)
put_attr_to_disk(stb->st_dev, stb->st_ino, attrib);
return(0);
}
void set_nw_archive_bit(int dev, ino_t inode)
/* only called for files */
{
uint32 attrib;
if ( (!get_attr_from_disk(dev, inode, &attrib))
&& !(attrib & FILE_ATTR_A)) {
attrib|=FILE_ATTR_A;
put_attr_to_disk(dev, inode, attrib);
}
}
/* trustees */
static void put_trustee_to_disk(int dev, ino_t inode, uint32 id, int trustee)
{
char buf[255];
char btrustee[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unx_xmkdir(buf, 0755);
sprintf(buf+l, "/%x", (unsigned int) id);
unlink(buf);
l=sprintf(btrustee, "%04x", (unsigned int) trustee);
symlink(btrustee, buf);
reseteuid();
}
static void free_trustees_from_disk(int dev, ino_t inode)
{
char buf[255];
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unx_xrmdir(buf);
reseteuid();
}
static int get_trustee_from_disk(int dev, ino_t inode, uint32 id)
{
char buf[255];
char btrustee[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x.t/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3],
(unsigned int) id);
seteuid(0);
l=readlink(buf, btrustee, 254);
reseteuid();
if (l > 0) {
unsigned int utrustee=0;
btrustee[l]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
return((int)utrustee);
}
}
return(-1);
}
static int scan_trustees_from_disk(int dev, ino_t inode, int *offset,
int max_trustees, uint32 *trustee_ids, int *trustees)
/* returns count of trustees if all ok */
{
char buf[255];
int l;
int count=0;
uint8 buf_uc[4];
DIR *d;
U32_TO_BE32(inode, buf_uc);
l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
d = opendir(buf);
if (NULL != d) {
uint8 *p=buf+l;
struct dirent *dirbuff;
*p++ = '/';
l=0;
if ((unsigned int)(*offset) >= MAX_U16)
*offset=0;
while (count < max_trustees &&
(dirbuff = readdir(d)) != (struct dirent*)NULL){
if (l++ > *offset) {
if (dirbuff->d_ino) {
char btrustee[255];
int len;
unsigned int id;
if (1 == sscanf(dirbuff->d_name, "%x", &id) && id > 0) {
strcpy(p, dirbuff->d_name);
len=readlink(buf, btrustee, 254);
if (len > 0) {
unsigned int utrustee=0;
btrustee[len]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
*trustee_ids++ = (uint32) id;
*trustees++ = (int) utrustee;
count++;
}
}
}
}
}
}
*offset=l;
closedir(d);
}
reseteuid();
return(count);
}
int get_own_trustee(int dev, ino_t inode, int look_for_trustee)
{
if (act_obj_id == 1){ /* supervisor */
if ( (look_for_trustee == TRUSTEE_S) || (look_for_trustee == TRUSTEE_M)
|| (look_for_trustee == (TRUSTEE_S | TRUSTEE_M)) )
return(look_for_trustee | TRUSTEE_S);
}
return(0);
}
int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee)
{
return(0);
#if 0
if (get_own_trustee(dev, inode, TRUSTEE_M) & (TRUSTEE_M | TRUSTEE_S)){
} else return(-0x8c); /* no modify privileges */
#endif
}
void free_nw_ext_inode(int dev, ino_t inode)
/* removes all attrib or trustees entries for files or dirs */
/* must be called after deleting nw file or dir */
{
free_attr_from_disk(dev, inode);
free_trustees_from_disk(dev, inode);
}

16
nwattrib.h Normal file
View File

@ -0,0 +1,16 @@
/* nwattrib.h 01-Feb-98 */
#ifndef _NWATTRIB_H_
#define _NWATTRIB_H_
extern uint32 get_nw_attrib_dword(struct stat *stb, int voloptions);
extern int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib);
extern int set_nw_attrib_byte (struct stat *stb, int voloptions, int battrib);
extern void set_nw_archive_bit(int dev, ino_t inode);
extern int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee);
extern void free_nw_ext_inode(int dev, ino_t inode);
#endif

View File

@ -1,5 +1,5 @@
/* nwbind.c */ /* nwbind.c */
#define REVISION_DATE "27-Nov-97" #define REVISION_DATE "04-Feb-98"
/* NCP Bindery SUB-SERVER */ /* NCP Bindery SUB-SERVER */
/* authentification and some message handling */ /* authentification and some message handling */

View File

@ -53,7 +53,7 @@ static uint8 readbuff[IPX_MAX_DATA];
static uint8 saved_readbuff[IPX_MAX_DATA]; static uint8 saved_readbuff[IPX_MAX_DATA];
static int saved_sequence=-1; static int saved_sequence=-1;
static int rw_buffer_size = 512; /* default */ static int rw_buffer_size = LOC_RW_BUFFERSIZE; /* default */
static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff; static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff;
static uint8 *requestdata = readbuff + sizeof(NCPREQUEST); static uint8 *requestdata = readbuff + sizeof(NCPREQUEST);
@ -285,7 +285,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
memset(xdata, 0, sizeof(struct XDATA)); memset(xdata, 0, sizeof(struct XDATA));
if ((result = nw_get_volume_name(volume, xdata->name))>-1){ if ((result = nw_get_volume_name(volume, xdata->name))>-1){
struct fs_usage fsp; struct fs_usage fsp;
if (!nw_get_fs_usage(xdata->name, &fsp, if (!nw_get_fs_usage(xdata->name, &fsp,
entry8_flags&0x40 )) { entry8_flags&0x40 )) {
int sector_scale=1; int sector_scale=1;
while (fsp.fsu_blocks/sector_scale > 0xffff) while (fsp.fsu_blocks/sector_scale > 0xffff)
@ -472,7 +472,6 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
if (code) completition = (uint8) -code; if (code) completition = (uint8) -code;
} else if (*p == 0xd){ /* Add Trustees to DIR */ } else if (*p == 0xd){ /* Add Trustees to DIR */
/******** AddTrustesstoDir ***************/ /******** AddTrustesstoDir ***************/
#if 0
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 div[3]; /* 0x0, dlen, ufunc */
@ -480,11 +479,15 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_id[4]; /* Trustee Object ID */
uint8 trustee_right_mask; uint8 trustee_right_mask;
uint8 pathlen; uint8 pathlen;
uint8 path; uint8 path[2];
} *input = (struct INPUT *) (ncprequest); } *input = (struct INPUT *) (ncprequest);
/* TODO !!!!!!!!!!!!!!!!!!!! */ int result = nw_add_trustee(
#endif input->dir_handle,
do_druck++; input->path, input->pathlen,
GET_BE32(input->trustee_id),
(int)input->trustee_right_mask,
0);
if (result) completition = (uint8) -result;
} else if (*p == 0xf){ /* rename dir */ } else if (*p == 0xf){ /* rename dir */
/******** Rename DIR *********************/ /******** Rename DIR *********************/
int dir_handle = (int) *(p+1); int dir_handle = (int) *(p+1);
@ -544,7 +547,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
result = nw_get_volume_name(volume, xdata->name); result = nw_get_volume_name(volume, xdata->name);
if (result > -1) { if (result > -1) {
struct fs_usage fsp; struct fs_usage fsp;
if (!nw_get_fs_usage(xdata->name, &fsp, if (!nw_get_fs_usage(xdata->name, &fsp,
entry8_flags&0x40 )) { entry8_flags&0x40 )) {
int sector_scale=1; int sector_scale=1;
while (fsp.fsu_blocks/sector_scale > 0xffff) while (fsp.fsu_blocks/sector_scale > 0xffff)
@ -695,8 +698,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
data_len = sizeof(struct XDATA); data_len = sizeof(struct XDATA);
} else completition = 0x9c; /* no more trustees */ } else completition = 0x9c; /* no more trustees */
} else completition = (uint8) (-result); } else completition = (uint8) (-result);
} else if (*p == 0x27) { /* Add Ext Trustees to DIR */ } else if (*p == 0x27) { /* Add Ext Trustees to DIR or File */
#if 0
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 div[3]; /* 0x0, dlen, ufunc */
@ -704,11 +706,15 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_id[4]; /* Trustee Object ID */
uint8 trustee_rights[2]; /* low - high */ uint8 trustee_rights[2]; /* low - high */
uint8 pathlen; uint8 pathlen;
uint8 path; uint8 path[2];
} *input = (struct INPUT *) (ncprequest); } *input = (struct INPUT *) (ncprequest);
/* TODO !!!!!!!!!!!!!!!!!!!! */ int result = nw_add_trustee(
#endif input->dir_handle,
do_druck++; input->path, input->pathlen,
GET_BE32(input->trustee_id),
GET_16(input->trustee_rights),
1); /* extended */
if (result) completition = (uint8) -result;
} else if (*p == 0x28){ } else if (*p == 0x28){
/* Scan File Physical ??? */ /* Scan File Physical ??? */
struct INPUT { struct INPUT {
@ -863,7 +869,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
/* uint8 len = *(requestdata+1); */ /* uint8 len = *(requestdata+1); */
uint8 ufunc = *(requestdata+2); uint8 ufunc = *(requestdata+2);
uint8 *rdata = requestdata+3; uint8 *rdata = requestdata+3;
switch (ufunc) { switch (ufunc) {
#if FUNC_17_02_IS_DEBUG #if FUNC_17_02_IS_DEBUG
case 0x02 : { case 0x02 : {
@ -962,24 +968,24 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
break; break;
case 0x64: { /* create queue */ case 0x64: { /* create queue */
#if 0 #if 0
int q_typ = GET_BE16(rdata); int q_typ = GET_BE16(rdata);
#endif #endif
int q_name_len = *(rdata+2); int q_name_len = *(rdata+2);
#if 0 #if 0
uint8 *q_name = rdata+3; uint8 *q_name = rdata+3;
#endif #endif
uint8 *dirhandle = rdata+3+q_name_len; uint8 *dirhandle = rdata+3+q_name_len;
int pathlen = *(rdata+3+q_name_len+1); int pathlen = *(rdata+3+q_name_len+1);
uint8 *path = rdata+3+q_name_len+2; uint8 *path = rdata+3+q_name_len+2;
uint8 new_path[257]; uint8 new_path[257];
int result = conn_get_full_path(*dirhandle, int result = conn_get_full_path(*dirhandle,
path, pathlen, new_path); path, pathlen, new_path);
if (result > -1) { if (result > -1) {
int diffsize = result - pathlen; int diffsize = result - pathlen;
*dirhandle = 0; *dirhandle = 0;
memcpy(path, new_path, result); memcpy(path, new_path, result);
if (diffsize) if (diffsize)
requestlen+=diffsize; /* !!!!!! */ requestlen+=diffsize; /* !!!!!! */
return(-1); /* nwbind must do the rest */ return(-1); /* nwbind must do the rest */
} else } else
@ -991,7 +997,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
case 0x79: /* create queue job and file */ case 0x79: /* create queue job and file */
return(-2); /* nwbind must do prehandling */ return(-2); /* nwbind must do prehandling */
case 0x6C: { /* Get Queue Job Entry old */ case 0x6C: { /* Get Queue Job Entry old */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
int job_id = GET_BE16(rdata+4); int job_id = GET_BE16(rdata+4);
@ -1000,7 +1006,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
requestlen+=6; /* !!!!!! */ requestlen+=6; /* !!!!!! */
} }
return(-1); /* nwbind must do the rest */ return(-1); /* nwbind must do the rest */
case 0x69: /* close file and start queue old ?? */ case 0x69: /* close file and start queue old ?? */
case 0x7f: { /* close file and start queue */ case 0x7f: { /* close file and start queue */
struct INPUT { struct INPUT {
@ -1106,12 +1112,25 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
case 0x21 : { /* Negotiate Buffer Size, Packetsize */ case 0x21 : { /* Negotiate Buffer Size, Packetsize */
uint8 *getsize=responsedata; uint8 *getsize=responsedata;
rw_buffer_size = min(LOC_RW_BUFFERSIZE, int buffer_size = (int) (GET_BE16((uint8*)requestdata));
(int) (GET_BE16((uint8*)requestdata))); /* Der Novell-Client der PAM's Net/E-Ethernetkarte
für Atari ST/TT meldet ein Packetsize von 0 wenn
nwserv NACH dem Novell Client NET_S1.PRG
gestartet wird. Da 0 in jedem Falle ein unsinniger
Wert ist, wird rw_buffer_size nicht verwendet.
Hayo Schmidt <100305.1424@compuserve.com>, 7-Dec-97
*/
if (buffer_size >= 512) {
rw_buffer_size = min(LOC_RW_BUFFERSIZE, buffer_size);
XDPRINTF((2,0, "Negotiate Buffer size = 0x%04x,(%d)",
(int) rw_buffer_size, (int) rw_buffer_size));
} else {
XDPRINTF((1,0, "Invalid Packetsize = %d, "
"Negotiate Buffer Size is set to %d",
buffer_size, rw_buffer_size));
}
U16_TO_BE16(rw_buffer_size, getsize); U16_TO_BE16(rw_buffer_size, getsize);
data_len = 2; data_len = 2;
XDPRINTF((2,0, "Negotiate Buffer size = 0x%04x,(%d)",
(int) rw_buffer_size, (int) rw_buffer_size));
} }
break; break;
@ -1389,7 +1408,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
uint8 data[2]; /* filename */ uint8 data[2]; /* filename */
} *input = (struct INPUT *)ncprequest; } *input = (struct INPUT *)ncprequest;
completition = completition =
(uint8) (-nw_chmod_datei((int)input->dir_handle, (uint8) (-nw_set_file_attributes((int)input->dir_handle,
input->data, (int)input->len, input->data, (int)input->len,
(int)input->attrib, (int)input->attrib,
(int)input->access)); (int)input->access));
@ -1874,13 +1893,13 @@ static void handle_after_bind()
int fnlen = (int) *(bindresponse + 3 * sizeof(int)); int fnlen = (int) *(bindresponse + 3 * sizeof(int));
uint8 objname[48]; uint8 objname[48];
/* ncpserv have changed the structure */ /* ncpserv have changed the structure */
if (ufunc==0x14) { if (ufunc==0x14) {
xstrmaxcpy(objname, requestdata+6, (int) *(requestdata+5)); xstrmaxcpy(objname, requestdata+6, (int) *(requestdata+5));
} else if (ufunc==0x18){ } else if (ufunc==0x18){
xstrmaxcpy(objname, requestdata+14, (int) *(requestdata+13)); xstrmaxcpy(objname, requestdata+14, (int) *(requestdata+13));
} else objname[0]='\0'; } else objname[0]='\0';
set_nw_user(*((int*)bindresponse), /* gid */ set_nw_user(*((int*)bindresponse), /* gid */
*((int*)(bindresponse+sizeof(int))), /* uid */ *((int*)(bindresponse+sizeof(int))), /* uid */
*((uint32*)(bindresponse + 2 * sizeof(int))), /* id */ *((uint32*)(bindresponse + 2 * sizeof(int))), /* id */
@ -1905,10 +1924,10 @@ static void handle_after_bind()
int result = creat_queue_job(q_id, qjob, int result = creat_queue_job(q_id, qjob,
responsedata, responsedata,
(ufunc == 0x68) ); (ufunc == 0x68) );
if (result > -1) if (result > -1)
data_len=result; data_len=result;
else else
completition = (uint8) -result; completition = (uint8) -result;
} }
break; break;
@ -1951,12 +1970,12 @@ static void handle_after_bind()
uint32 q_id = GET_BE32(input->queue_id); uint32 q_id = GET_BE32(input->queue_id);
uint8 *qjob = bindresponse; uint8 *qjob = bindresponse;
int result = service_queue_job(q_id, qjob, int result = service_queue_job(q_id, qjob,
responsedata, responsedata,
ufunc==0x71); ufunc==0x71);
if (result > -1) if (result > -1)
data_len=result; data_len=result;
else else
completition = (uint8) -result; completition = (uint8) -result;
} }
break; break;
@ -2219,7 +2238,7 @@ int main(int argc, char **argv)
while (fl_get_int >= 0) { while (fl_get_int >= 0) {
int data_len = read(0, readbuff, sizeof(readbuff)); int data_len = read(0, readbuff, sizeof(readbuff));
/* this read is a pipe or a socket read, /* this read is a pipe or a socket read,
* depending on CALL_NWCONN_OVER_SOCKET * depending on CALL_NWCONN_OVER_SOCKET
*/ */
@ -2256,10 +2275,10 @@ int main(int argc, char **argv)
saved_sequence = -1; saved_sequence = -1;
} else { /* this calls I must handle, it is a request */ } else { /* this calls I must handle, it is a request */
time_t act_time=time(NULL); time_t act_time=time(NULL);
if (act_time > last_time+300 && saved_sequence == -1) { if (act_time > last_time+300 && saved_sequence == -1) {
/* ca. 5 min. reset wdogs */ /* ca. 5 min. reset wdogs */
call_nwbind(1); call_nwbind(1);
last_time=act_time; last_time=act_time;
} }

View File

@ -1,5 +1,5 @@
/* nwfile.c 26-Nov-97 */ /* nwfile.c 01-Feb-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -27,7 +27,9 @@
#include "nwshare.h" #include "nwshare.h"
#include "nwfile.h" #include "nwfile.h"
#include "connect.h" #include "connect.h"
#include "nwattrib.h"
#include "nwconn.h" #include "nwconn.h"
#include "unxfile.h"
# include <sys/mman.h> # include <sys/mman.h>
@ -91,6 +93,7 @@ static int new_file_handle(uint8 *unixname, int task)
fh->fd = -2; fh->fd = -2;
fh->offd = 0L; fh->offd = 0L;
fh->tmodi = 0L; fh->tmodi = 0L;
fh->modified = 0;
fh->st_ino = 0; fh->st_ino = 0;
strcpy((char*)fh->fname, (char*)unixname); strcpy((char*)fh->fname, (char*)unixname);
fh->fh_flags = 0; fh->fh_flags = 0;
@ -116,8 +119,15 @@ static int free_file_handle(int fhandle)
fh->size_mmap = 0; fh->size_mmap = 0;
} }
close(fh->fd); close(fh->fd);
if (fh->st_ino) if (fh->st_ino) {
share_file(fh->st_dev, fh->st_ino, 0); share_file(fh->st_dev, fh->st_ino, 0);
if (fh->modified) {
fh->modified=0;
#if NEW_ATTRIB_HANDLING
set_nw_archive_bit(fh->st_dev, fh->st_ino);
#endif
}
}
} }
if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags) if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags)
&& !(FH_IS_READONLY & fh->fh_flags) ) { && !(FH_IS_READONLY & fh->fh_flags) ) {
@ -225,7 +235,11 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
? get_real_access(stbuff) : -1; ? get_real_access(stbuff) : -1;
int did_grpchange = 0; int did_grpchange = 0;
if (dowrite && (voloptions & VOL_OPTION_READONLY)) {
if (dowrite && (acc > -1) && (acc & W_OK) && !(creatmode&0x8) &&
(get_nw_attrib_dword(stbuff, voloptions) & FILE_ATTR_R))
completition = -0x94;
else if (dowrite && (voloptions & VOL_OPTION_READONLY)) {
completition = (creatmode&3) ? -0x84 : -0x94; completition = (creatmode&3) ? -0x84 : -0x94;
} else if (acc > -1) { } else if (acc > -1) {
/* do exist */ /* do exist */
@ -516,8 +530,15 @@ int nw_close_file(int fhandle, int reset_reuse)
fh->size_mmap = 0; fh->size_mmap = 0;
} }
result=close(fh->fd); result=close(fh->fd);
if (fh->st_ino) if (fh->st_ino) {
share_file(fh->st_dev, fh->st_ino, 0); share_file(fh->st_dev, fh->st_ino, 0);
if (fh->modified) {
fh->modified=0;
#if NEW_ATTRIB_HANDLING
set_nw_archive_bit(fh->st_dev, fh->st_ino);
#endif
}
}
} }
fh->fd = -1; fh->fd = -1;
if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE) if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE)
@ -723,22 +744,16 @@ int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->offd > -1L) { if (fh->offd > -1L) {
size = write(fh->fd, data, size); size = write(fh->fd, data, size);
fh->offd+=(long)size; fh->offd+=(long)size;
if (!fh->modified)
fh->modified++;
} else size = -1; } else size = -1;
return(size); return(size);
} else { /* truncate FILE */ } else { /* truncate FILE */
int result; int result = unx_ftruncate(fh->fd, offset);
#ifdef LINUX
result = ftruncate(fh->fd, offset);
#else
struct flock flockd;
flockd.l_type = 0;
flockd.l_whence = SEEK_SET;
flockd.l_start = offset;
flockd.l_len = 0;
result = fcntl(fh->fd, F_FREESP, &flockd);
#endif
XDPRINTF((5,0,"File %s is truncated, result=%d", fh->fname, result)); XDPRINTF((5,0,"File %s is truncated, result=%d", fh->fname, result));
fh->offd = -1L; fh->offd = -1L;
if (!fh->modified)
fh->modified++;
return(result); return(result);
} }
} }
@ -763,6 +778,8 @@ int nw_server_copy(int qfhandle, uint32 qoffset,
if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L &&
lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { lseek(fhz->fd, zoffset, SEEK_SET) > -1L) {
retsize = 0; retsize = 0;
if (size && !fhz->modified)
fhz->modified++;
while (size) { while (size) {
int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff))); int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff)));
if (xsize > 0){ if (xsize > 0){
@ -875,20 +892,26 @@ int get_nwfd(int fhandle)
int nw_unlink(int volume, char *name) int nw_unlink(int volume, char *name)
{ {
struct stat stbuff; struct stat stbuff;
if (get_volume_options(volume) & VOL_OPTION_IS_PIPE) int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_IS_PIPE)
return(0); /* don't delete 'pipe commands' */ return(0); /* don't delete 'pipe commands' */
else if (get_volume_options(volume) & VOL_OPTION_READONLY) else if (get_volume_options(volume) & VOL_OPTION_READONLY)
return(-0x8a); /* don't delete 'readonly' */ return(-0x8a); /* don't delete 'readonly' */
if (stat(name, &stbuff)) if (stat(name, &stbuff))
return(-0x9c); /* wrong path */ return(-0x9c); /* wrong path */
if (get_nw_attrib_dword(&stbuff, voloptions) & FILE_ATTR_R)
return(-0x8a); /* don't delete 'readonly' */
if ( -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x12|0x8) if ( -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x12|0x8)
|| ( !(entry8_flags&0x10) && || ( !(entry8_flags&0x10) &&
-1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x11|0x4)) ) -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x11|0x4)) )
return(-0x8a); /* NO Delete Privileges */ return(-0x8a); /* NO Delete Privileges, file is shared open */
if (!unlink(name)) if (!unlink(name)) {
free_nw_ext_inode(stbuff.st_dev, stbuff.st_ino);
return(0); return(0);
}
return(-0x8a); /* NO Delete Privileges */ return(-0x8a); /* NO Delete Privileges */
} }

View File

@ -1,4 +1,4 @@
/* nwfile.h 21-Jul-97 */ /* nwfile.h 09-Feb-98 */
#ifndef _NWFILE_H_ #ifndef _NWFILE_H_
#define _NWFILE_H_ #define _NWFILE_H_
#include "extpipe.h" #include "extpipe.h"
@ -10,6 +10,7 @@ typedef struct {
uint8 *p_mmap; /* for use with mmap */ uint8 *p_mmap; /* for use with mmap */
int size_mmap; int size_mmap;
time_t tmodi; /* modification TIME */ time_t tmodi; /* modification TIME */
int modified; /* is file modified / written */
FILE_PIPE *f; /* for PIPE */ FILE_PIPE *f; /* for PIPE */
int fh_flags; /* 2 = PIPE */ int fh_flags; /* 2 = PIPE */
/* 4 = don't reuse after close */ /* 4 = don't reuse after close */

View File

@ -1,5 +1,5 @@
/* nwroute.c 17-Jul-97 */ /* nwroute.c 08-Feb-98 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -699,14 +699,19 @@ static int look_for_interfaces(void);
void send_sap_rip_broadcast(int mode) void send_sap_rip_broadcast(int mode)
/* mode=0, standard broadcast */ /* mode=0, standard broadcast */
/* mode=1, first trie */ /* mode=1, first trie */
/* mode=2, shutdown */ /* mode=2, shutdown */
/* mode=3, update routes */ /* mode=3, update routes */
/* mode=4, resend to net */ /* mode=4, resend to net */
/* mode=5, force update routes */
{ {
static int flipflop=1; static int flipflop=1;
int force_print_routes=(mode == 1) ? 1 : 0; int force_print_routes=(mode == 1) ? 1 : 0;
if (mode == 5) {
force_print_routes++;
mode = 3;
}
if (auto_detect_interfaces) if (auto_detect_interfaces)
force_print_routes += look_for_interfaces(); force_print_routes += look_for_interfaces();
if (mode) { if (mode) {

View File

@ -1,7 +1,7 @@
/* nwserv.c 08-Oct-97 */ /* nwserv.c 08-Feb-98 */
/* MAIN Prog for NWSERV + NWROUTED */ /* MAIN Prog for NWSERV + NWROUTED */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -1120,11 +1120,11 @@ static void close_all(void)
#ifdef LINUX #ifdef LINUX
# if INTERNAL_RIP_SAP # if INTERNAL_RIP_SAP
#if 0 #if 1
if (!(ipx_flags&1)) { if (!(ipx_flags&1)) {
for (j=0; j<count_net_devices;j++) { for (j=0; j<count_net_devices;j++) {
NW_NET_DEVICE *nd=net_devices[j]; NW_NET_DEVICE *nd=net_devices[j];
if (nd->is_up) { if (nd->is_up==1) { /* only no auto interfaces */
XDPRINTF((1, 0, "Close Device=%s, frame=%d", XDPRINTF((1, 0, "Close Device=%s, frame=%d",
nd->devname, nd->frame)); nd->devname, nd->frame));
exit_dev(nd->devname, nd->frame); exit_dev(nd->devname, nd->frame);
@ -1165,7 +1165,7 @@ static void sig_chld(int rsig)
} }
#endif #endif
static int fl_get_int=0; static int fl_get_int=0; /* 1 .. 8 */
static void sig_quit(int rsig) static void sig_quit(int rsig)
{ {
signal(rsig, SIG_IGN); signal(rsig, SIG_IGN);
@ -1196,12 +1196,24 @@ static void handle_usr1_request(void)
send_sap_rip_broadcast(3); send_sap_rip_broadcast(3);
} }
static void handle_usr2_request(void)
{
XDPRINTF((2,0, "Got USR2, force sending rip/sap"));
send_sap_rip_broadcast(5);
}
static void sig_usr1(int rsig) static void sig_usr1(int rsig)
{ {
fl_get_int|=4; fl_get_int|=4;
signal(rsig, sig_usr1); signal(rsig, sig_usr1);
} }
static void sig_usr2(int rsig)
{
fl_get_int|=8;
signal(rsig, sig_usr2);
}
static void set_sigs(int mode) static void set_sigs(int mode)
{ {
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
@ -1211,12 +1223,14 @@ static void set_sigs(int mode)
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
signal(SIGUSR1, SIG_IGN); signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
} else { } else {
signal(SIGTERM, sig_quit); signal(SIGTERM, sig_quit);
signal(SIGQUIT, sig_quit); signal(SIGQUIT, sig_quit);
signal(SIGINT, sig_quit); signal(SIGINT, sig_quit);
signal(SIGHUP, sig_hup); signal(SIGHUP, sig_hup);
signal(SIGUSR1, sig_usr1); signal(SIGUSR1, sig_usr1);
signal(SIGUSR2, sig_usr2);
} }
} }
@ -1225,12 +1239,17 @@ static int server_is_down=0;
static int usage(char *prog) static int usage(char *prog)
{ {
#if !IN_NWROUTED #if !IN_NWROUTED
fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]|y]\n", prog); fprintf(stderr, "usage:\t%s [-V|-h|-f|-u|-k[q]|y]\n", prog);
fprintf(stderr, "or:\t%s -a device frame netnum\n", prog);
fprintf(stderr, "or:\t%s -d device frame\n", prog);
#else #else
fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]]\n", prog); fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]]\n", prog);
#endif #endif
fprintf(stderr, "\t-V: print version\n"); fprintf(stderr, "\t-V: print version\n");
fprintf(stderr, "\t-a: add interface, frames = '802.2' '802.3' 'etherii' 'snap'\n");
fprintf(stderr, "\t-d: delete interface.\n");
fprintf(stderr, "\t-h: send HUP to main process\n"); fprintf(stderr, "\t-h: send HUP to main process\n");
fprintf(stderr, "\t-f: force send rip/sap and update routing int. table\n");
fprintf(stderr, "\t-u: update int. routing table\n"); fprintf(stderr, "\t-u: update int. routing table\n");
fprintf(stderr, "\t-k: stop main process, wait for it.\n"); fprintf(stderr, "\t-k: stop main process, wait for it.\n");
fprintf(stderr, "\t-kq: don't wait till stop of main process\n"); fprintf(stderr, "\t-kq: don't wait till stop of main process\n");
@ -1254,9 +1273,51 @@ int main(int argc, char **argv)
if (*a == '-') { if (*a == '-') {
while (*(++a)) { while (*(++a)) {
switch (*a) { switch (*a) {
case 'a' :
case 'd' :
if ( (*a == 'a' && argc - j == 4)
|| (*a == 'd' && argc - j == 3) ) {
int result;
int frame=-1;
uint32 netnum=0L;
char buf[256];
strcpy(buf, argv[j+2]);
upstr(buf);
if (!strcmp(buf, "802.3"))
frame=IPX_FRAME_8023;
else if (!strcmp(buf, "802.2"))
frame=IPX_FRAME_8022;
else if (!strcmp(buf, "SNAP"))
frame=IPX_FRAME_SNAP;
else if (!strcmp(buf, "ETHERNET_II"))
frame=IPX_FRAME_ETHERII;
else if (!strcmp(buf, "ETHERII"))
frame=IPX_FRAME_ETHERII;
# ifdef IPX_FRAME_TR_8022
else if (!strcmp(buf, "TOKEN"))
frame=IPX_FRAME_TR_8022;
# endif
if (*a == 'a' && frame > -1) {
char dummy;
if (sscanf(argv[j+3], "%ld%c", &netnum, &dummy) != 1)
sscanf(argv[j+3], "%lx", &netnum);
}
if (netnum > 0)
result=add_device_net(argv[j+1], frame, netnum);
else if ( *a == 'd') {
exit_dev(argv[j+1], frame);
result=0;
} else
return(usage(argv[0]));
return((result<0) ? 1 : 0);
} else
return(usage(argv[0]));
case 'h' : init_mode = 1; break; case 'h' : init_mode = 1; break;
case 'k' : init_mode = 2; break; case 'k' : init_mode = 2; break;
case 'u' : init_mode = 3; break; case 'u' : init_mode = 3; break;
case 'f' : init_mode = 5; break;
case 'q' : if (init_mode == 2) init_mode=4; break; case 'q' : if (init_mode == 2) init_mode=4; break;
case 'v' : case 'v' :
case 'V' : fprintf(stderr, "\n%s:Version %d.%d.pl%d\n", case 'V' : fprintf(stderr, "\n%s:Version %d.%d.pl%d\n",
@ -1369,8 +1430,10 @@ int main(int argc, char **argv)
if (fl_get_int) { if (fl_get_int) {
if (fl_get_int & 1) if (fl_get_int & 1)
handle_hup_reqest(); handle_hup_reqest();
else if (fl_get_int & 4) if (fl_get_int & 4)
handle_usr1_request(); handle_usr1_request();
if (fl_get_int & 8)
handle_usr2_request();
if (fl_get_int & 2) if (fl_get_int & 2)
down_server(); down_server();
fl_get_int=0; fl_get_int=0;

View File

@ -1,5 +1,5 @@
/* nwvolume.c 28-Nov-97 */ /* nwvolume.c 01-Feb-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -38,6 +38,7 @@ int loaded_namespaces=0;
uint8 *home_dir=NULL; uint8 *home_dir=NULL;
int home_dir_len=0; int home_dir_len=0;
char *path_vol_inodes_cache=NULL; char *path_vol_inodes_cache=NULL;
char *path_attributes=NULL;
static int max_nw_vols=MAX_NW_VOLS; static int max_nw_vols=MAX_NW_VOLS;
@ -82,6 +83,7 @@ void nw_init_volumes(FILE *f)
used_nw_volumes = 0; used_nw_volumes = 0;
loaded_namespaces = 0; loaded_namespaces = 0;
new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache"); new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache");
new_str(path_attributes, "/var/lib/nwserv/attrib");
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){ if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){
uint8 sysname[256]; uint8 sysname[256];
@ -183,6 +185,8 @@ void nw_init_volumes(FILE *f)
} }
} else if (what==40) { /* path for vol/dev/inode->path cache */ } else if (what==40) { /* path for vol/dev/inode->path cache */
new_str(path_vol_inodes_cache, buff); new_str(path_vol_inodes_cache, buff);
} else if (what==46) { /* path for attribute handling */
new_str(path_attributes, buff);
} }
} /* while */ } /* while */
} }

View File

@ -1,5 +1,5 @@
/* nwvolume.h 28-Nov-97 */ /* nwvolume.h 01-Feb-98 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -80,6 +80,7 @@ extern int loaded_namespaces;
extern uint8 *home_dir; extern uint8 *home_dir;
extern int home_dir_len; extern int home_dir_len;
extern char *path_vol_inodes_cache; /* for namespace routines */ extern char *path_vol_inodes_cache; /* for namespace routines */
extern char *path_attributes; /* for attribute handling */
extern void nw_init_volumes(FILE *f); extern void nw_init_volumes(FILE *f);
extern void nw_setup_vol_opts(int act_gid, int act_uid, extern void nw_setup_vol_opts(int act_gid, int act_uid,

10
tools.c
View File

@ -1,5 +1,5 @@
/* tools.c 26-Nov-97 */ /* tools.c 08-Feb-98 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -444,6 +444,8 @@ void init_tools(int module, int options)
sig = SIGTERM; sig = SIGTERM;
} else if (options == 3) { /* update tables */ } else if (options == 3) { /* update tables */
sig = SIGUSR1; sig = SIGUSR1;
} else if (options == 5) { /* force update tables */
sig = SIGUSR2;
} else { } else {
errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" , errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" ,
kill_pid, pidfn); kill_pid, pidfn);
@ -466,12 +468,12 @@ void init_tools(int module, int options)
fprintf(stderr, "\n%s not yet stopped!\n", get_modstr()); fprintf(stderr, "\n%s not yet stopped!\n", get_modstr());
exit(1); exit(1);
} else if (sig == SIGUSR1 || sig == SIGTERM) { /* we try twice */ } else if (sig == SIGUSR1 || sig == SIGTERM) { /* we try twice */
sleep(2); sleep(2);
kill(kill_pid, sig); kill(kill_pid, sig);
} }
} }
exit(0); exit(0);
} else if (options == 1 || options == 2 || options == 3 || options == 4) { } else if (options == 1 || options == 2 || options == 3 || options == 4|| options==5) {
errorp(11, "INIT", "Program not yet running." ); errorp(11, "INIT", "Program not yet running." );
exit(1); exit(1);
} }

View File

@ -1,6 +1,6 @@
/* unxfile.c: 09-Jul-97*/ /* unxfile.c: 05-Feb-98*/
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,6 +18,7 @@
*/ */
#include "net.h" #include "net.h"
#include <dirent.h>
#include "unxfile.h" #include "unxfile.h"
int unx_mvdir(uint8 *oldname, uint8 *newname) int unx_mvdir(uint8 *oldname, uint8 *newname)
@ -67,6 +68,30 @@ int unx_xmkdir(char *unixname, int mode)
return(-1); return(-1);
} }
int unx_xrmdir(char *unixname)
/* removes complete directory if possible */
{
DIR *d = opendir(unixname);
if (NULL != (d = opendir(unixname))) {
struct dirent *dirbuff;
int len = strlen(unixname);
char *buf = xmalloc(len + 300);
char *p = buf+len;
memcpy(buf, unixname, len);
*p++ = '/';
while ((dirbuff = readdir(d)) != (struct dirent*)NULL){
if (dirbuff->d_ino) {
strcpy(p, dirbuff->d_name);
if (unlink(buf) && unx_xrmdir(buf))
break;
}
}
xfree(buf);
closedir(d);
}
return(rmdir(unixname));
}
#if 0 #if 0
int unx_mvdir(uint8 *oldname, uint8 *newname) int unx_mvdir(uint8 *oldname, uint8 *newname)
{ {
@ -80,3 +105,17 @@ int unx_mvdir(uint8 *oldname, uint8 *newname)
} }
#endif #endif
int unx_ftruncate(int fd, uint32 size)
{
#ifdef LINUX
return(ftruncate(fd, size));
#else
struct flock flockd;
flockd.l_type = 0;
flockd.l_whence = SEEK_SET;
flockd.l_start = size;
flockd.l_len = 0;
result = fcntl(fd, F_FREESP, &flockd);
#endif
}

View File

@ -1,5 +1,5 @@
/* unxfile.h: 09-Jul-97*/ /* unxfile.h: 05-Feb-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -21,5 +21,8 @@ extern int unx_mvdir(uint8 *oldname, uint8 *newname);
extern int unx_mvfile(uint8 *oldname, uint8 *newname); extern int unx_mvfile(uint8 *oldname, uint8 *newname);
extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname); extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname);
extern int unx_xmkdir(char *unixname, int mode); extern int unx_xmkdir(char *unixname, int mode);
extern int unx_xrmdir(char *unixname);
extern int unx_ftruncate(int fd, uint32 size);
#endif #endif