mars_nwe-0.98.pl05

This commit is contained in:
Mario Fetka 2011-11-13 00:38:57 +01:00
parent 758f245d47
commit 1eac63223b
36 changed files with 1506 additions and 567 deletions

167
connect.c
View File

@ -1,4 +1,4 @@
/* connect.c 04-Oct-96 */
/* connect.c 07-Nov-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -42,7 +42,7 @@ int used_dirs=0;
int act_uid=-1;
int act_gid=-1;
int act_obj_id=0L; /* not login */
int entry8_flags=0; /* special login/logout/flags */
int entry8_flags=0; /* special flags, see examples nw.ini, entry 8 */
int act_umode_dir=0;
int act_umode_file=0;
@ -793,7 +793,7 @@ static int nw_path_ok(NW_PATH *nwpath)
d++;
} /* while */
if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff)
&& (stbuff.st_mode & S_IFMT) == S_IFDIR)
&& S_ISDIR(stbuff.st_mode))
return(stbuff.st_ino);
result = -0x9c; /* wrong path */
}
@ -1009,48 +1009,56 @@ time_t nw_2_un_time(uint8 *d, uint8 *t)
return(mktime(&s_tm));
}
static 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 */
{
/* Attribute */
/* 0x01 readonly */
/* 0x02 hidden */
/* 0x04 System */
/* 0x10 IS_DIR */
/* 0x20 Archive Flag */
/* 0x80 Sharable */ /* TLINK (TCC 2.0) don't like it ???? */
if (!mode) {
int is_dir=S_ISDIR(stb->st_mode);
/* UNIX access -> NW access */
attrib = 0x20;
if (!is_dir) {
attrib = FILE_ATTR_A;
} else {
attrib = FILE_ATTR_DIR;
}
if (act_uid) {
/* if not root */
int acc=get_real_access(stb);
if (!(acc & W_OK)) {
attrib |= 0x1; /* RO */
attrib |= FILE_ATTR_R; /* RO */
}
if (!(acc & R_OK)) {
attrib |= 0x2; /* We say hidden here */
attrib |= FILE_ATTR_H; /* We say hidden here */
}
}
/* only shared if gid == gid && x Flag */
if ((act_gid == stb->st_gid) && (stb->st_mode & S_IXGRP))
attrib |= 0x80; /* shared flag */
if (!is_dir) {
if ((act_gid == stb->st_gid) && (stb->st_mode & S_IXGRP))
attrib |= FILE_ATTR_SHARE; /* shared flag */
}
return(attrib);
} else {
/* NW access -> UNIX access */
int mode = S_IRUSR | S_IRGRP;
if (attrib & 0x2) /* hidden */
if (attrib & FILE_ATTR_H) /* hidden */
stb->st_mode &= ~mode;
else
stb->st_mode |= mode;
mode = S_IWUSR | S_IWGRP;
if (attrib & 0x1) /* R/O */
if (attrib & FILE_ATTR_R) /* R/O */
stb->st_mode &= ~mode;
else
stb->st_mode |= mode;
if (attrib & 0x80) /* Shared */
if (attrib & FILE_ATTR_SHARE) /* Shared */
stb->st_mode |= S_IXGRP;
else
stb->st_mode &= ~S_IXGRP;
@ -1058,6 +1066,36 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode)
}
}
int un_nw_rights(struct stat *stb)
/* returns eff rights of file/dir */
/* needs some more work */
{
int rights=0xfb; /* first all rights, but not TRUSTEE_O */
if (act_uid) {
/* if not root */
int is_dir = S_ISDIR(stb->st_mode);
int acc=get_real_access(stb);
int norights= TRUSTEE_A; /* no access control rights */
if (!(acc & W_OK)) {
if (is_dir) {
norights |= TRUSTEE_C;
norights |= TRUSTEE_E;
} else {
norights |= TRUSTEE_W; /* RO */
}
}
if (!(acc & R_OK)) {
if (is_dir) {
norights |= TRUSTEE_F; /* SCAN */
} else {
norights |= TRUSTEE_R; /* Not for Reading */
}
}
rights &= ~norights;
} else rights|= TRUSTEE_S; /* Supervisor */
return(rights);
}
static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
NW_PATH *nwpath)
{
@ -1088,8 +1126,12 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb,
strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name));
d->attrib=0; /* d->name could be too long */
upstr(d->name);
d->attrib = 0x10; /* Verzeichnis */
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
un_date_2_nw(stb->st_mtime, d->create_date, 1);
un_time_2_nw(stb->st_mtime, d->create_time, 1);
U32_TO_BE32(get_file_owner(stb), d->owner_id);
@ -1277,8 +1319,14 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
NW_PATH zielpath;
int completition=conn_get_kpl_path(&quellpath, dir_handle, q, qlen, 0);
if (!completition > -1){
#if 1
/* I do not know anymore why I did these ??? */
memcpy(&zielpath, &quellpath, sizeof(NW_PATH));
strmaxcpy(zielpath.fn, z, zlen);
#else
/* and NOT these, perhaps this will also be ok ?! -- TODO -- */
completition=conn_get_kpl_path(&zielpath, dir_handle, z, zlen, 0);
#endif
if (completition > -1) {
int optq = get_volume_options(quellpath.volume, 1);
int optz = get_volume_options(zielpath.volume, 1);
@ -1286,6 +1334,11 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
(optz & VOL_OPTION_IS_PIPE)) completition = -0x8b;
else if ((optq & VOL_OPTION_READONLY) ||
(optz & VOL_OPTION_READONLY)) completition = -0x8b;
/* patch from Sven Norinder <snorinder@sgens.ericsson.se> :09-Nov-96 */
else if (optz & VOL_OPTION_DOWNSHIFT)
downstr(zielpath.fn);
else
upstr(zielpath.fn);
}
if (completition > -1){
int result;
@ -1353,7 +1406,7 @@ static int change_dir_entry( NW_DIR *dir, int volume,
void nw_exit_connect(void)
{
if (connect_is_init) {
init_file_module();
init_file_module(-1);
}
}
@ -1386,7 +1439,7 @@ int nw_init_connect(void)
d++;
}
init_file_module();
init_file_module(-1);
if (connect_is_init) {
k = 0;
@ -1458,6 +1511,7 @@ int nw_free_handles(int task)
}
d++;
}
init_file_module(task);
}
return(0);
}
@ -1591,7 +1645,7 @@ int nw_open_dir_handle( int dir_handle,
/*
* Routine returns handle to use in searchroutines.
* RETURN=errcode ( <0 ) or ACCES Rights
* RETURN=errcode ( <0 ) or eff. ACCES Rights
*/
{
@ -1603,11 +1657,13 @@ int nw_open_dir_handle( int dir_handle,
completition = new_dir_handle((ino_t)completition, &nwpath);
if (completition > -1) {
struct stat stb;
DIR_HANDLE *dh = &(dir_handles[completition-1]);
stat(dh->unixname, &stb);
*volume = dh->volume;
*dir_id = completition;
*searchsequence = MAX_U16;
completition = 0xff; /* all rights */
completition = (uint8)un_nw_rights(&stb); /* eff. rights */
}
XDPRINTF((5,0,"NW_OPEN_DIR_2: completition = 0x%x",
completition));
@ -1636,24 +1692,32 @@ int nw_free_dir_handle(int dir_handle, int task)
} else return(-0x9b); /* wrong handle */
}
int alter_dir_handle(int targetdir, int volume, uint8 *path,
int inode, int task)
/* targetdir will be changed */
{
if (targetdir > 0 && --targetdir < used_dirs
&& dirs[targetdir].is_temp != 2) {
/* do not change special temphandles */
XDPRINTF((5,0,"Change dhandle:%d(%d) -> '%d:%s'", targetdir+1, task,
volume, path));
return(change_dir_entry(&dirs[targetdir],
volume, path, inode,
-1, -1, 0, task));
/* here the existing handle is only modified */
} else return(-0x9b); /* BAD DIR Handle */
}
int nw_set_dir_handle(int targetdir, int dir_handle,
uint8 *data, int len, int task)
/* targetdirs gets path of dirhandle + data */
{
NW_PATH nwpath;
int inode = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1);
if (inode > -1){
if (targetdir > 0 && --targetdir < used_dirs
&& dirs[targetdir].is_temp != 2) {
/* do not change special temphandles */
XDPRINTF((2,0,"Change dhandle:%d(%d) -> `%s`", targetdir+1, task,
conn_get_nwpath_name(&nwpath)));
return(change_dir_entry(&dirs[targetdir],
nwpath.volume, nwpath.path, inode,
-1, -1, 0, task));
/* here the existing handle is only modified */
} else return(-0x9b); /* BAD DIR Handle */
}
if (inode > -1)
inode = alter_dir_handle(targetdir, nwpath.volume, nwpath.path,
inode, task);
return(inode); /* invalid PATH */
}
@ -1698,15 +1762,15 @@ int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus)
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 0));
if (stat(unname, &stbuff) ||
(!modus && (stbuff.st_mode & S_IFMT) != S_IFDIR) ) {
(!modus && !S_ISDIR(stbuff.st_mode)) ) {
completition = -0x9c;
} else completition=0xff; /* all rights */
} else completition=un_nw_rights(&stbuff); /* eff. rights */
return(completition);
}
int nw_creat_open_file(int dir_handle, uint8 *data, int len,
NW_FILE_INFO *info, int attrib, int access,
int creatmode)
int creatmode, int task)
/*
* creatmode: 0 = open | 1 = creat | 2 = creatnew & 4 == save handle
* attrib ??
@ -1718,7 +1782,7 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len,
if (completition > -1) {
struct stat stbuff;
completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0),
&stbuff, attrib, access, creatmode);
&stbuff, attrib, access, creatmode, task);
if (completition > -1)
get_file_attrib(info, &stbuff, &nwpath);
@ -1771,7 +1835,7 @@ static int s_nw_scan_dir_info(int dir_handle,
U32_TO_BE32(get_file_owner(&stbuff), owner);
un_date_2_nw(stbuff.st_mtime, subdatetime, 1);
un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1);
return(0xff);
return(un_nw_rights(&stbuff));
}
strcpy((char*)dirname, (char*)wild);
} /* while */
@ -1784,7 +1848,7 @@ static int s_nw_scan_dir_info(int dir_handle,
U32_TO_BE32(get_file_owner(&stbuff), owner);
un_date_2_nw(stbuff.st_mtime, subdatetime, 1);
un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1);
return(0xff);
return(un_nw_rights(&stbuff));
}
}
/* return(-0x9c); NO MORE INFO */
@ -1824,7 +1888,8 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
int volume,
uint8 *path)
{
uint8 spath[14];
uint8 spath[14];
uint32 nw_owner=get_file_owner(stb);
int voloptions=get_volume_options(volume, 1);
f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12);
@ -1839,9 +1904,12 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
un_date_2_nw(stb->st_mtime, f->created.date, 0);
un_time_2_nw(stb->st_mtime, f->created.time, 0);
U32_TO_BE32(nw_owner, f->created.id);
un_date_2_nw(stb->st_mtime, f->updated.date, 0);
un_time_2_nw(stb->st_mtime, f->updated.time, 0);
U32_TO_BE32(nw_owner, f->updated.id);
U32_TO_BE32(get_file_owner(stb), f->created.id);
memcpy(&(f->updated), &(f->created), sizeof(NW_DOS_FILE_INFO));
un_date_2_nw(stb->st_atime, f->last_access_date, 0);
U32_TO_32(stb->st_size, f->size);
}
@ -1856,7 +1924,7 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
strmaxcpy(spath, path, 12);
upstr(spath);
strncpy((char*)f->name, (char*)spath, f->namlen);
f->attributes[0] = 0x10; /* Dir */
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
un_date_2_nw(stb->st_mtime, f->created.date,0);
un_time_2_nw(stb->st_mtime, f->created.time,0);
U32_TO_BE32(get_file_owner(stb), f->created.id);
@ -1893,7 +1961,7 @@ int nw_scan_a_directory(uint8 *rdata,
conn_get_nwpath_name(&nwpath),
stbuff.st_uid, stbuff.st_gid));
if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) {
if ( S_ISDIR(stbuff.st_mode)) {
get_dos_dir_attrib(&(scif->u.d), &stbuff,
nwpath.volume, nwpath.fn);
} else {
@ -1936,7 +2004,6 @@ static int my_match(uint8 *s, uint8 *p)
} else if (dot) {
if (dot++ > 3) return(0);
} else if (len == 8) return(0);
if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s))
|| (*p | 0x20) != (*s | 0x20)))
return(0);
@ -1949,10 +2016,26 @@ static int get_match(uint8 *unixname, uint8 *p)
{
DIR *d;
uint8 *pp;
#if 0
uint8 *p1;
#endif
int inode=0;
if (!p || !*p) return(1);
*p = '\0';
pp=p+1;
while (*pp == '/') ++pp;
#if 0
p1=strchr(pp, '/');
if (!p1) p1=pp+strlen(pp);
if (p1 > pp+4 && *(p1-4) == '.'
&& *(p1-3) == '_'
&& *(p1-2) == '_'
&& *(p1-1) == '_' ) {
*(p1-4) = '\0';
inode=atoi(pp);
*(p1-4) = '.';
}
#endif
if (NULL != (d=opendir(unixname))) {
struct dirent *dirbuff;
XDPRINTF((10, 0, "opendir OK unixname='%s' pp='%s'", unixname, pp));
@ -1961,7 +2044,7 @@ static int get_match(uint8 *unixname, uint8 *p)
int len;
if (dirbuff->d_ino) {
XDPRINTF((10, 0, "get match found d_name='%s'", dirbuff->d_name));
if (0 != (len=my_match(dirbuff->d_name, pp))) {
if ((dirbuff->d_ino ==inode) || 0 != (len=my_match(dirbuff->d_name, pp))) {
memcpy(pp, dirbuff->d_name, len);
XDPRINTF((10, 0, "get match, match OK"));
closedir(d);

View File

@ -1,6 +1,30 @@
/* connect.h 29-Sep-96 */
/* connect.h 06-Nov-96 */
#ifndef _CONNECT_H_
#define _CONNECT_H_
/* some TRUSTEE defines */
#define TRUSTEE_R 0x01 /* Read Rights */
#define TRUSTEE_W 0x02 /* Write Rights */
#define TRUSTEE_O 0x04 /* Open, not used ?? by Novell */
#define TRUSTEE_C 0x08 /* Creat */
#define TRUSTEE_E 0x10 /* Erase */
#define TRUSTEE_A 0x20 /* Access Control */
#define TRUSTEE_F 0x40 /* File Scan */
#define TRUSTEE_M 0x80 /* Modify */
/* ........................................ */
#define TRUSTEE_S 0x100 /* Supervisor */
/* <-------------- File Attributes -------------> */
#define FILE_ATTR_NORMAL 0x00000000
#define FILE_ATTR_R 0x00000001
#define FILE_ATTR_H 0x00000002
#define FILE_ATTR_S 0x00000004
#define FILE_ATTR_DIR 0x00000010
#define FILE_ATTR_A 0x00000020
#define FILE_ATTR_SHARE 0x00000080
typedef struct {
DIR *f;
char unixname[256]; /* kompletter unixname */
@ -112,7 +136,7 @@ extern void nw_exit_connect(void);
extern int nw_free_handles(int task);
extern int nw_creat_open_file(int dir_handle, uint8 *data, int len,
NW_FILE_INFO *info, int attrib, int access, int mode);
NW_FILE_INFO *info, int attrib, int access, int mode, int task);
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,
@ -165,6 +189,9 @@ extern int nw_open_dir_handle( int dir_handle,
extern int nw_free_dir_handle(int dir_handle, int task);
extern int alter_dir_handle(int targetdir, int volume, uint8 *path,
int inode, int task);
extern int nw_set_dir_handle(int targetdir, int dir_handle,
uint8 *data, int len, int task);
@ -198,11 +225,10 @@ extern int used_dirs;
extern int act_uid;
extern int act_gid;
extern int act_obj_id; /* not login == 0 */
extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */
extern int act_umode_dir;
extern int act_umode_file;
extern int entry8_flags; /* special login/logout/flags */
extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
uint8 *data, int len, int only_dir) ;
extern int conn_get_kpl_unxname(char *unixname,
@ -233,6 +259,8 @@ 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 time_t nw_2_un_time(uint8 *d, uint8 *t);
extern int un_nw_attrib(struct stat *stb, int attrib, int mode);
extern int un_nw_rights(struct stat *stb);
extern void un_time_2_nw(time_t time, uint8 *d, int high_low);

36
doc/BUGS Normal file
View File

@ -0,0 +1,36 @@
If you have problems.
---------------------
- LOOK FOR KERNEL IPX CODE INSTALLED.
CONFIG_IPX=y (or m and ipx modul loaded (insmod ipx)).
- Look for using NO 'full internal net'. (kernel switch)
CONFIG_IPX_INTERN=n.
- Please always read doc/INSTALL[.ger], doc/README[.ger],
doc/FAQS and examples/nw.ini.
Very important sections in nwserv.conf(nw.ini) are:
Section 1: volumes
Section 3: Number of the internal network
Section 4: IPX-devices
Section 6: version-"spoofing"
Section 12: supervisor-login
If you do not have success, please make one try with
the distributed config file(s) without changing it.
- Important NEWS are reported in doc/NEWS.
- set nwserv.conf debug switches 101 .. 10x to '1',
make a new try with a new started nwserv and look
into the log-file (/tmp/nw.log).
Perhaps you can recognize the problem. :)
some short notes for problem- or bug-reports.
---------------------------------------------
- report your running environment
full mars_nwe version, example: 0.98.pl5
linux-kernel, 2.0.23
exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. )
changes you made into nwserv.conf(nw.ini), config.h.
- report whether your client runs correct under a 'real Novell-Server'.
( if you have one ;) )
Known problems / solutions:
---------------------------
- see doc/FAQS

View File

@ -1,6 +1,6 @@
Sorry, this is in German only.
User important notes are in the NEWS file.
Aenderungen in mars_nwe bis zum : 04-Oct-96
Aenderungen in mars_nwe bis zum : 09-Nov-96
--------------------------------
Erste 'oeffentliche' Version
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -187,7 +187,7 @@ Erste 'oeffentliche' Version
- nwserv.stations erweitert um 'station connect restrictions'.
- Datei Access um 'supplementary groups' erweitert.
Open File ruft gegebenfalls setegid() auf.
- Als File-Creator wird nun der aktuelle mars_nwer User zurueckgegeben,
- Als File-Creator wird nun der aktuelle mars_nwe User zurueckgegeben,
falls st_uid == uid aktueller User.
- call 0x3d in 0x3b (commit file) umbenannt.
- segmentation violation in build_verz_name (connect.c) korrigiert.
@ -219,4 +219,31 @@ Erste 'oeffentliche' Version
Sonderbehandlung von handle 1.
- Login Restrictions. (station restrictions) eingebaut.
<----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Namespace Routinen (0x57), Unterfunktionen:
0x09 : (Set Short Dir Handle)
0x14 : (Search For File Or Subdir Set)
0x1c : (Get Full Path String)
0x1d : (Get eff rights)
eingebaut. ( fuer client32 )
- call 0x18 (EndOfJob) schliesst nun alle noch offenen Dateien
der aktuellen Task.
- File Server Copy (0x4a) funktioniert nun korrekt.
- neuer Schalter in config.h eingebaut: 'HANDLE_ALL_SAP_TYPS'
dadurch wird nicht nur TYP 4 herausgefiltert, sondern es werden
alle SAP-Typen in die ServerTabelle bzw. Bindery eingetragen.
Anregung von paul.sweetland@bbc.co.uk.
- sicheres Protokoll zwischen nwserv u. nwbind bzw. ncpserv
eingebaut.
- Schalter 302 erweitert um 0x2 fuer split Routing Datei.
- OS/2 namespace Dateimatchroutine abgeaendert, so dass Wildcard
'*.*' auf alle Dateien funktioniert.
- sehr einfache eff. rights Emulation eingebaut.
- NCP responses task ist nun gleich request task.
- Entry 8 um Schalter 0x2 erweitert.
- Openfile routine, share open etwas abgeaendert.
- IPX_MAX_DATA vergroessert. IPX_DATA_GR_546 abgeaendert.
- kleinen patch ( upper/lowercase Handling ) von
Sven Norinder <snorinder@sgens.ericsson.se>
in nwconn,mv_dir eingebaut.
<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -12,3 +12,22 @@ A: This is for automatic inserting UNIX Users as mars_nwe users.
All of these automatic inserted users will get the password
as the crypted bindery password.
Q: File write will not work under WIN3.1, WfW
A: Try updating C:\WINDOWS\SYSTEM\STORAGE.DLL. I find that earlier
versions of this file evince the problem you describe under Windows 3.1
and 3.11. Precisely when this problem went away in STORAGE.DLL I don't
know, but versions dated October 1994 or later are working for us.
( John Rigby )
Q: I do not have longfilenamesupport.
A: Give the volume the 'O' flag.
Set section 6 in nwserv.conf to > 0.
Win95, by default, does not use long filenames on a netware 3.11
server. This is documented in the resource kit help file and
elsewhere. You should read that to find out the ramifications, but
with real netware I've had good luck using the recommended registry
settings. Here is a registry import file:
REGEDIT4
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR]
"SupportLFN"=hex:02

View File

@ -1,4 +1,10 @@
# in this files are some notes for user of mars_nwe.
------09-Nov-96--- 0.98.pl5 ----------
- now Novell Client32 should works.
- new config.h flag. 'HANDLE_ALL_SAP_TYPS'
- section 8: new flag 0x2 added. (see examples/nw.ini).
- section 302: enhanced for 'split routing info file'.
- config.h: 'IPX_DATA_GR_546' enhanced.
------04-Oct-96--- 0.98.pl4 ----------
- new sections 8 + 9 in nw.ini (nwserv.conf).
Section 8: special login/logout/security flags.

View File

@ -5,9 +5,10 @@ solve this problem
In the PIPE filesystem either shell scripts or Linux programs can be
stored. These programs are treated on the client side (eg DOS) like
simple files. Opening these files via the client causes a popen of the
programs. The server passes as the first parameter either CREAT READ
or WRITE, depending on the mode of the corresponding openfile
simple files. Reading or writing these files via the client causes
a popen of the programs.
The server passes as the first parameter either READ
or WRITE, depending on the mode of the corresponding first read or write
operation. This allows the PIPE filesystem to provide a direct
interface between client applications and Linux programs.
@ -16,8 +17,6 @@ simple shell script, which was stored in the PIPE-filesystem:
#!/bin/sh
case "$1" in
'CREAT')
;;
'WRITE')
cd /u3 && tar -xf - 2>> /tmp/tar.in
# restore directory /u3/mar
@ -38,28 +37,15 @@ the Copy command (->save), or the local file can be copied into this
A simple print operation can be achieved with the following script:
#!/bin/sh
case "$1" in
'WRITE')
/usr/bin/lpr
;;
*)
;;
esac
/usr/bin/lpr
This allows you to print under dos/windows without capturing.
Various unix programs can be invoked with the following script, after
it has been linked with the required program name.
#!/bin/sh
case "$1" in
'READ')
/usr/bin/`basename $0`
;;
*)
;;
esac
In the examples dir exist the two programpairs comm<->unxcomm
and sendm<->unxsendm as additional examples for using 'PIPE-filesystem'.
With comm/unxcomm it is very easy to start simple Linux programs
by your client.
for examples: ps, lpq, lprm ...
I would appreciate hearing about further documented applications of
the PIPE filesystem or suggestions for other ways of using it.

View File

@ -6,12 +6,12 @@ Ein schneller Loesungsansatz ergab das 'PIPE Filesystem'.
In dem Pipe Filesystem koennen Shell Scripte oder
Linux Programme hinterlegt werden.
Diese Programme werden bei dem Client (z.B. DOS) wie einfache
Diese Programme werden von dem Client (z.B. DOS) wie einfache
Dateien behandelt.
Ein Oeffnen dieser Dateien ueber den Client bewirkt
Ein Lese oder Schreibzugriff auf diese Dateien ueber den Client bewirkt
einen popen dieser Programme. Der Server uebergibt
als 1. Parameter entweder 'CREAT', 'READ' oder 'WRITE'
je nach Modus der jeweiligen Openfile Operation.
als 1. Parameter entweder 'READ' oder 'WRITE'
je nach Modus des ersten Zugriffes (Read oder Write).
Das 'PIPE-Filesystem' bietet damit eine direkte Schnittstelle
zwischen Client Anwendungen und Linux Programmen.
@ -20,8 +20,6 @@ Shell Script, welches im PIPE-Filesystem hinterlegt wurde.
#!/bin/sh
case "$1" in
'CREAT')
;;
'WRITE')
cd /u3 && tar -xf - 2>> /tmp/tar.in
# restore directory /u3/mar
@ -39,31 +37,22 @@ lokale Datei 'kopiert' werden ( -> Sichern ) bzw. es
kann die lokale Datei auf diese 'Pipe Datei' kopiert werden.
( -> Ruecksichern )
Ein einfaches Drucken kann z.B. mit folgendem Script realisiert werden.
#!/bin/sh
case "$1" in
'WRITE')
/usr/bin/lpr
;;
*)
;;
esac
Der Aufruf diverser Unix Programme kann mit folgenden Script
erfolgen das auf die entsprechenden Programmnamen gelinkt wurde.
Ein einfaches Drucken kann z.B. mit folgendem Mini Script realisiert werden.
Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf
/usr/bin/lpr.
#!/bin/sh
case "$1" in
'READ')
/usr/bin/`basename $0`
;;
*)
;;
esac
/usr/bin/lpr
Dadurch kann ein capture unter DOS/Windows entfallen.
In dem Verzeichnis examples gibt es als zusaetzliches Beispiel
die Programmpaare unxcomm<->comm und sendm<->unxsendm.
Mittels unxcomm/comm ist es sehr einfach moeglich einige
Linux Befehle vom Client aus aufzurufen.
z.B. : ps, lpq, lprm usw.
Ueber weitere dokumentierte Anwendungen bzw. Anregungen zu dem
PIPE-Filesystem wuerde ich mich freuen.
Martin

View File

@ -1,7 +1,7 @@
Begin3
Title: mars_nwe
Version: 0.98.pl4
Entered-date: 04-Oct-96
Version: 0.98.pl5
Entered-date: 11-Nov-96
Description: Full netware-emulator (src), beta.
Supports file-services, bindery-services,
printing-services, routing-services.
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@stover.f.eunet.de (Martin Stover)
Maintained-by: mstover@stover.f.eunet.de (Martin Stover)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
200kB mars_nwe-0.98.pl4.tgz
200kB mars_nwe-0.98.pl5.tgz
Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
Copying-policy: GNU

View File

@ -1,5 +1,5 @@
#define DO_IPX_SEND_TEST 1
/* emutli.c 28-Apr-96 */
/* emutli.c 04-Oct-96 */
/*
* One short try to emulate TLI with SOCKETS.
*/
@ -51,16 +51,18 @@ void set_sock_debug(int sock)
}
}
void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so)
{
memcpy(i->net, &so->sipx_network, IPX_NET_SIZE + IPX_NODE_SIZE);
memcpy(i->sock, &so->sipx_port, 2);
#define sock2ipxadr(i, so) \
{ \
memcpy((i)->net, &(so)->sipx_network, IPX_NET_SIZE + IPX_NODE_SIZE); \
(i)->sock[0] = ((uint8*)(&(so)->sipx_port))[0]; \
(i)->sock[1] = ((uint8*)(&(so)->sipx_port))[1]; \
}
void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i)
{
memcpy(&so->sipx_network, i->net, IPX_NET_SIZE + IPX_NODE_SIZE);
memcpy(&so->sipx_port, i->sock, 2);
#define ipx2sockadr(so, i) \
{ \
memcpy(&(so)->sipx_network, (i)->net, IPX_NET_SIZE + IPX_NODE_SIZE); \
((uint8*)(&(so)->sipx_port))[0] = (i)->sock[0]; \
((uint8*)(&(so)->sipx_port))[1] = (i)->sock[1]; \
}
void set_emu_tli(void)

View File

@ -94,8 +94,6 @@ struct pollfd {
extern void set_locipxdebug(int debug);
extern void set_sock_debug(int sock);
extern void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so);
extern void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i);
extern void set_emu_tli(void);
extern int poll(struct pollfd *fds, unsigned long nfds, int timeout);

View File

@ -30,7 +30,7 @@ static int usage(char *progname)
int main(int argc, char **argv)
{
char *unxcomm=getenv("UNXCOMM");
char *unxcomm=getenv(ENV_UNXCOMM);
if (NULL == unxcomm) unxcomm=DEFAULT_COMM;
if (argc > 1) {
int fdout = open(unxcomm, O_RDWR);

0
examples/comm.exe Executable file → Normal file
View File

View File

@ -1,4 +1,4 @@
/* config.h: 18-Jul-96 */
/* config.h: 04-Nov-96 */
/* some of this config is needed by make, others by cc */
#define DO_DEBUG 1 /* compile in debug code */
@ -32,7 +32,9 @@
#define MAX_CONNECTIONS 5 /* max. number of simultaneous */
/* connections handled by mars_nwe */
#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */
#define IPX_DATA_GR_546 1 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */
/* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */
/* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */
#define USE_MMAP 1 /* use mmap systen call */
@ -58,6 +60,10 @@
#define MAX_NW_SERVERS 40 /* max. number of nw-servers on your */
/* network */
#define HANDLE_ALL_SAP_TYPS 0 /* if set to 0 only SAP-Typ 4 Servers */
/* will be put into routing table and */
/* if set to 1 all SAP Typs will be */
/* used. */
/* <--------------- next is for linux only ----------------------------> */
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */
/* -------------------- */

View File

@ -1,5 +1,5 @@
#!/bin/sh
# mk.li 10-Jul-96 ###
# mk.li 19-Oct-96
# please edit this file !
mk()
@ -15,7 +15,25 @@ mk()
if [ $V_VPATH = '..' ] ; then
cd ..;
fi
chmod 666 $ERRFILE
if [ -f $ERRFILE ] ; then
chmod 666 $ERRFILE
fi
}
print_error()
{
if [ "$UNX" = 'linux' ]; then
if [ ! -f /usr/include/ndbm.h ] ; then
echo "-------------------------------------------------------------"
echo "probably you have a broken Linux installation because"
echo "'/usr/include/ndbm.h' the include file for the Linux database"
echo "is missing."
echo "-------------------------------------------------------------"
fi
fi
echo ""
echo "The errors are also reported in '$ERRFILE'"
echo "============================================================="
}
TOLOWER='tr "[A-Z]" "[a-z]"'
@ -23,7 +41,8 @@ UNX=`uname -s | $TOLOWER`
MASCHINE=`uname -m`
MK_PPID=$$
export MK_PPID
trap 'echo "Error: Try again :)" && exit 1' 1
trap 'print_error; exit 1' 1
case $UNX in
linux)
@ -55,7 +74,7 @@ fi
TMP=/tmp
INSTALL=install
;;
########### USL UNIX ##############
########### SYSV (UnixWare) ##############
unix_sv)
V_VPATH="."
OBJDIR="."

View File

@ -2,7 +2,7 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux.
#
# last change: 04-Oct-96
# last changed: 09-Nov-96
# This file specifies which Linux-resources (printers, users, directories)
# should be accessible to the DOS-clients via "mars_nwe". Furthermore
@ -72,6 +72,7 @@
#
# m removable volume (e.g. cd-roms) or volumes, which
# should be remountable when mars_nwe is running.
# Should also be used for 'HOME' volumes.
# r volume is read-only and always reports "0 byte free"
# (this is intended for copies of CD-ROMs on harddisks)
# o (lowercase o)
@ -91,7 +92,7 @@
# Examples:
# 1 SYS /var/local/nwe/SYS k
# 1 CDROM /cdrom kmr
# 1 HOME ~ k
# 1 HOME ~ km
1 SYS /u3/SYS/ k
@ -259,8 +260,11 @@
#
# SERVER_VERSION: the version-number reported to DOS-clients
# 0 Version 2.15 (default)
# 1 Version 3.11
# 2 Version 3.12 (not implemented yet)
# 1 Version 3.11 (will be default soon)
# 2 Version 3.12 (burst mode is not implemented yet)
#
# If you want to use longfilenamesupport and/or namespace routines
# you should set this section to '1'.
# -------------------------------------------------------------------------
#
@ -301,12 +305,16 @@
7 0
# Section 8: special login/logout/security flags.
# Section 8: special login/logout/security and other flags.
# =========================================================================
# Flags
# 0x1 allow changing dir/accessing other files than login/*
# when not logged in, if the client supports it.
# ( this was standard till mars_nwe-0.98.pl4 )
# 0x2 switch on strange compatibility mode for opening files.
# If an opencall do an open for writing but
# the file is readonly then this call will not fail
# but open the file readonly.
#
# other flags may follow.
# value will be interpreted as hex value.
@ -537,7 +545,7 @@
101 1 # debug NWSERV
102 0 # debug NCPSERV
103 0 # debug NWCONN
104 0 # debug (start) NWCLIENT
104 0 # debug (start) NWCLIENT, should *always* be '0' !
105 0 # debug NWBIND
106 1 # debug NWROUTED
@ -561,9 +569,12 @@
300 1 # > 0 print routing info to file every x broadcasts.
# ( normally minutes )
301 /tmp/nw.routes # filename of logfile
302 1 # 1 = creat new routing info file
# 0 = append to this file
302 0x1 # flags will be interpreted as hex value.
# 0 = append to this file
# & 0x1 = creat new routing info file
# & 0x2 = split info into several files
# (extensions = .1, .2, .3 ... )
# Section 310: watchdogs

70
examples/sendm.c Normal file
View File

@ -0,0 +1,70 @@
/* sendm.c 23-Oct-96 */
/*
* simple demo for a sendmail acces under DOS
* DOS <-> UNX command handling using PIPE filesystem.
* can be used with unxsendm for UNX.
*
* Can also be used under Linux for ncpfs <-> mars_nwe.
* but do not use it directly (the opencall will destroy unxsendm)!!
*
* QUICK + DIRTY !!!
*/
#define ENV_UNXCOMM "UNXSENDM"
#ifdef LINUX
# define DEFAULT_COMM "/pipes/unxsendm"
# else
# define DEFAULT_COMM "p:/unxsendm"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#ifndef LINUX
# include <io.h>
#endif
#include <fcntl.h>
int main(int argc, char **argv)
{
char *unxcomm=getenv(ENV_UNXCOMM);
int fdout;
int fdin;
int is_pipe=isatty(0) ? 0 :1;
if (NULL == unxcomm)
unxcomm=DEFAULT_COMM;
fdout = open(unxcomm, O_RDWR);
fdin = dup(fdout);
if (fdout > -1 && fdin > -1) {
char **pp=argv+1;
unsigned char b=32;
int size;
char buf[1024];
while(--argc >0) {
write(fdout, *pp, strlen(*pp));
++pp;
write(fdout, &b, 1);
}
b=0;
write(fdout, &b, 1);
close(fdout);
fdout=dup(fdin);
if (6 == (size = read(fdin, buf, 6)) && !memcmp(buf, "+++++\n", 6)) {
/* now write stdin -> sendmail */
if (is_pipe) {
while (0 < (size = fread(buf, 1, sizeof(buf), stdin)))
write(fdout, buf, size);
}
} else if (size > 0)
write(1, buf, size); /* probably errormessage */
close(fdout);
/* now we print errors */
while (0 < (size = read(fdin, buf, sizeof(buf)))) {
write(1, buf, size);
}
close(fdin);
return(0);
} else
fprintf(stderr, "Cannot open PIPECOMMAND '%s'\n", unxcomm);
return(1);
}

View File

@ -1,6 +1,12 @@
/* unxcomm.c 24-Oct-96 */
/* simple UNX program to work together with 'comm' */
/* to domonstrate usage of pipefilesystem */
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
static char **build_argv(int bufsize, char *command, int len)
/* routine returns **argv for use with execv routines */
@ -38,15 +44,28 @@ static char **build_argv(int bufsize, char *command, int len)
}
#define MAXARGLEN 1024
int bl_read(int fd, void *buf, int size)
{
fd_set fdin;
struct timeval t;
int result;
FD_ZERO(&fdin);
FD_SET(fd, &fdin);
t.tv_sec = 1; /* 1 sec should be enough */
t.tv_usec = 0;
result = select(fd+1, &fdin, NULL, NULL, &t);
if (result > 0)
result=read(fd, buf, size);
return(result);
}
int main(int argc, char *argv[])
{
int status=fcntl(0, F_GETFL);
int size;
char buf[MAXARGLEN+1024];
if (status != -1) fcntl(0, F_SETFL, status|O_NONBLOCK);
close(2);
dup2(1,2);
if (-1 < (size=read(0, buf, MAXARGLEN))){
if (0 < (size=bl_read(0, buf, MAXARGLEN))){
char **argvv=build_argv(sizeof(buf), buf, size);
if (argvv) {
char path[300];

53
examples/unxsendm.c Normal file
View File

@ -0,0 +1,53 @@
/* unxsendm.c 23-Oct-96 */
/* simple UNX program to work together with 'pipe-filesystem'
* and DOS sendm.exe to get sendmail functionality under DOS
* QUICK + DIRTY !!!
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#define MAXARGLEN 100
int bl_read(int fd, void *buf, int size)
{
fd_set fdin;
struct timeval t;
int result;
FD_ZERO(&fdin);
FD_SET(fd, &fdin);
t.tv_sec = 1; /* 1 sec should be enough */
t.tv_usec = 0;
result = select(fd+1, &fdin, NULL, NULL, &t);
if (result > 0)
result=read(fd, buf, size);
return(result);
}
int main(int argc, char *argv[])
{
int size;
char buf[1024];
close(2);
dup2(1,2); /* we want stdout and errout */
if (-1 < (size=bl_read(0, buf, MAXARGLEN))){
FILE *f;
char path[MAXARGLEN+200];
buf[size]='\0';
sprintf(path, "/usr/sbin/sendmail %s", buf);
f=popen(path, "w");
if (NULL != f) {
write(1, "+++++\n", 6);
while (0 < (size=bl_read(0, buf, sizeof(buf)))){
fwrite(buf, size, 1, f);
}
pclose(f);
return(0);
}
perror(path);
} else
perror("read stdin");
return(1);
}

View File

@ -1,5 +1,5 @@
#if 0
#makefile.unx 11-Sep-96
#makefile.unx 04-Oct-96
#endif
VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0
V_L=98
P_L=4
P_L=5
#define D_P_L 1
DISTRIB=mars_nwe
@ -118,6 +118,7 @@ OBJ8= $(OBJ6)
OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
$(EMUTLIOBJ1) $(NWROUTE_O) \
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\
nwqueue$(O) nameos2$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) \
$(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \
$(PROG7)$(O) $(PROG8)$(O)
@ -164,6 +165,8 @@ $(C)$(O):
n_all: $(PROGS)
@echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes
@echo "please take a look into doc/NEWS !" >> $(VPATH)/.mk.notes
n_routed: $(PROG7)
@ -191,7 +194,12 @@ echo "$(M_FILENAME_NW_INI) created from nw.ini"; \
echo ""; \
echo "********************************************************"; \
echo ""; \
fi; cd $(OBJDIR) )
fi; \
echo "If you have problems, please read 'doc/BUGS' before"; \
echo "sending mail to mailinglist or me."; \
echo ""; \
echo "********************************************************"; \
cd $(OBJDIR) )
n_reboot: n_install
-nwserv -k

View File

@ -198,7 +198,8 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
switch (pc) {
case '.' :
case 1000: if (*s && ('.' != *s++) ) return(0);
case 1000: if ( (*p!= 0xff || (*(p+1) != '*' && *(p+1) != 0xaa))
&& *s && ('.' != *s++) ) return(0);
break;
case '?' :

View File

@ -1,8 +1,7 @@
/* namspace.c 09-Aug-96 : NameSpace Services, mars_nwe */
/* namspace.c 09-Nov-96 : NameSpace Services, mars_nwe */
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */
/* Its very dirty till now. */
/* namespace calls should be only activated for testings */
/* Its still very dirty, but it should work fairly well */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
@ -284,15 +283,28 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath,
int k = -1;
int npbeg = strlen(nwpath->path);
uint8 *pp = nwpath->path+npbeg;
#if 0
int perhaps_inode_mode = 0;
#endif
XDPRINTF((2, 0, "entry add_hpath_to_nwpath: %s",
debug_nwpath_name(nwpath)));
while (!result && ++k < nwp->components) {
int len = (int) *(pp_pathes++);
uint8 *p = pp_pathes;
pp_pathes+=len;
if (!len) { /* this means '..' ! */
if (pp > nwpath->path) {
pp=strrchr((char*)nwpath->path, '/');
if (!pp)
pp=nwpath->path;
*pp='\0';
npbeg = pp - nwpath->path;
continue;
} else {
result=-0x9c; /* wrong path */
goto leave_build_nwpath;
}
}
if (!k && nwpath->volume == -1) { /* first component is volume */
if ((nwpath->volume=nw_get_volume_number(p, len)) < 0) {
/* something not OK */
@ -310,8 +322,15 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath,
}
while (i--) {
if (*p == 0xae) *pp++ = '.';
else if (*p == 0xaa || *p == '*' ) {
if (*p == 0xae || *p == '.') {
*pp++ = '.';
#if 0
if (nwpath->namespace == NAME_DOS) {
if (i==3 && *(p+1) == '_')
perhaps_inode_mode++;
}
#endif
} else if (*p == 0xaa || *p == '*' ) {
*pp++ = '*';
nwpath->has_wild++;
} else if (*p == 0xbf || *p == '?' ) {
@ -334,7 +353,7 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath,
*pp = '\0';
} /* else */
} /* while */
if (nwpath->volume < 0) result=-0x9c;
if (nwpath->volume < 0) result=-0x9c; /* wrong path */
leave_build_nwpath:
if ((!result) && (!act_obj_id) && !(entry8_flags & 1)) {
if (nwpath->volume)
@ -354,7 +373,7 @@ leave_build_nwpath:
if (!result) {
NW_VOL *v = &nw_volumes[nwpath->volume];
if (nwpath->namespace == NAME_DOS || nwpath->namespace == NAME_OS2) {
if (v->options & VOL_OPTION_IGNCASE) {
if (v->options & VOL_OPTION_IGNCASE /* || perhaps_inode_mode*/) {
int nplen= (int)(pp - nwpath->path) - npbeg;
uint8 unixname[1024]; /* should be enough */
memcpy(unixname, v->unixname, v->unixnamlen);
@ -376,6 +395,12 @@ leave_build_nwpath:
downstr(nwpath->path);
else
upstr(nwpath->path);
#if 0
if (nwpath->namespace == NAME_DOS){
}
#endif
}
}
}
@ -460,7 +485,6 @@ static int find_base_entry(int volume, uint32 basehandle)
}
}
}
/* now we test whether it is the root of volume */
if (0 < ino) {
struct stat statb;
@ -594,6 +618,118 @@ static int build_base(int namespace,
return(result);
}
static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname)
{
uint8 *ss=e->nwpath.fn;
int len=0;
int pf=0;
int is_ok=1;
int options=get_volume_options(e->nwpath.volume, 1);
for (; *ss; ss++){
if (*ss == '.') {
if (pf++) { /* no 2. point */
is_ok=0;
break;
}
len=0;
} else {
++len;
if ((pf && len > 3) || len > 8) {
is_ok=0;
break;
}
if (!(options & VOL_OPTION_IGNCASE)){
if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */
if (*ss >= 'A' && *ss <= 'Z') {
is_ok=0;
break;
}
} else { /* only upshift chars */
if (*ss >= 'a' && *ss <= 'z') {
is_ok=0;
break;
}
}
}
}
}
if (is_ok) {
strcpy(fname, e->nwpath.fn);
upstr(fname);
return(strlen(fname));
} else {
return(sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino));
}
}
#if 0
typedef struct {
int anz;
DIR_BASE_ENTRY *ee[MAX_DIR_BASE_ENTRIES];
} BASE_COMPONENTS;
static BASE_COMPONENTS *get_path_components(DIR_BASE_ENTRY *dbe)
{
BASE_COMPONENTS *be=(BASE_COMPONENTS*)xcmalloc(sizeof(BASE_COMPONENTS));
uint8 *p=dbe->nwpath.path;
uint8 *lastpp = p+strlen(p);
int len=0;
int k=0;
int done=(lastpp==dbe->nwpath.path ||
(lastpp==dbe->nwpath.path+1 && *(dbe->nwpath.path)== '/' ));
result = insert_get_base_entry(nwpath, namespace, 0);
int l;
while (!done) {
uint8 *pp=lastpp;
while (pp > dbe->nwpath.path && *pp!='/') --pp;
if (*pp != '/') {
done++;
l = lastpp-pp;
} else {
pp++;
l = lastpp-pp;
lastpp=pp-1;
}
if (!k++) {
} else {
}
if (l > 255)
return(-0xff);
len+=(l+1);
*(p++) = (uint8)l;
memcpy(p, pp, l);
*(p+l)='\0';
k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
p+=l;
}
/* now as last element the volume */
l=strlen(nw_volumes[dbe->nwpath.volume].sysname);
len+=(l+1);
*(p++) = (uint8)l;
memcpy(p, nw_volumes[dbe->nwpath.volume].sysname, l);
*(p+l)='\0';
k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
if (len > 400)
return(-0xff); /* we support only 'short' pathnames */
}
#endif
int nw_generate_dir_path(int namespace,
NW_HPATH *nwp,
uint8 *ns_dir_base,
@ -619,13 +755,15 @@ int nw_generate_dir_path(int namespace,
return(result);
}
static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
static int build_dir_info(DIR_BASE_ENTRY *dbe,
int namespace,
uint32 infomask, uint8 *p)
{
N_NW_PATH *nwpath=&(dbe->nwpath);
struct stat *stb=&(nwpath->statb);
int result = 76;
int result = 76; /* minimumsize */
uint32 owner = get_file_owner(stb);
memset(p, 0, result);
memset(p, 0, result+2);
if (infomask & INFO_MSK_DATA_STREAM_SPACE) {
U32_TO_32(stb->st_size, p);
@ -633,12 +771,11 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
p += 4;
if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
uint32 mask=0L;
if (S_ISDIR(stb->st_mode)) mask |= FILE_ATTR_DIR;
U32_TO_32(mask, p);
uint32 attrib = (uint32) un_nw_attrib(stb, 0, 0);
U32_TO_32(attrib, p);
p += 4;
U16_TO_16((uint16)(mask & 0xFFFF), p);
p +=2;
U16_TO_16((uint16)(attrib & 0xFFFF), p);
p += 2;
} else p+=6;
if (infomask & INFO_MSK_DATA_STREAM_SIZE) {
@ -658,7 +795,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
p +=2;
un_date_2_nw(stb->st_mtime, p, 0);
p +=2;
U32_TO_32(owner, p);
U32_TO_BE32(owner, p); /* HI-LOW ! */
p +=4;
} else p+=8;
@ -667,7 +804,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
p +=2;
un_date_2_nw(stb->st_mtime, p, 0);
p +=2;
U32_TO_32(owner, p);
U32_TO_BE32(owner, p); /* HI-LOW ! */
p +=4;
un_date_2_nw(stb->st_atime, p, 0); /* access date */
p +=2;
@ -678,12 +815,12 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
p +=2;
un_date_2_nw(0, p, 0);
p +=2;
U32_TO_32(0, p);
U32_TO_BE32(0, p); /* HI-LOW */
p +=4;
} else p+=8;
if (infomask & INFO_MSK_RIGHTS_INFO) {
U16_TO_16(0, p);
if (infomask & INFO_MSK_RIGHTS_INFO) { /* eff. rights ! */
U16_TO_16( un_nw_rights(stb), p);
}
p +=2;
@ -710,21 +847,26 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p)
} else p+=12;
if (infomask & INFO_MSK_NAME_SPACE_INFO){
U32_TO_32(0, p); /* Creator of the name space number */
U32_TO_32(namespace, p); /* using namespace */
}
p +=4;
/* ---------------------------------------------- */
if (infomask & INFO_MSK_ENTRY_NAME) {
*p = (uint8) strlen(nwpath->fn);
result++;
if (*p) {
memcpy(p+1, nwpath->fn, (int) *p);
if (namespace == NAME_DOS) {
*p=(uint8) build_dos_name(dbe, p+1);
result += (int) *p;
} else {
*p = (uint8) strlen(nwpath->fn);
if (*p) {
memcpy(p+1, nwpath->fn, (int) *p);
result += (int) *p;
}
}
}
XDPRINTF((3, 0, "build_dir_info:path=%s, result=%d, basehandle=0x%x, mask=0x%lx",
debug_nwpath_name(nwpath), result, dbe->basehandle, infomask));
XDPRINTF((3, 0, "build_d_i:space=%d, path=%s, result=%d, handle=0x%x, mask=0x%lx",
namespace, debug_nwpath_name(nwpath), result, dbe->basehandle, infomask));
return(result);
}
int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp,
@ -734,13 +876,14 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp,
/* returns sizeof info_mask
* the sizeof info_mask is NOT related by the infomask.
* But the _valid_ info is.
* must return -0xff for file not found !
*/
{
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL);
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info");
result = build_dir_info(dbe, infomask, responsedata);
result = build_dir_info(dbe, destnamspace, infomask, responsedata);
} else {
XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x",
-result));
@ -748,6 +891,25 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp,
return(result);
}
int nw_get_eff_rights(int namespace, NW_HPATH *nwp,
int destnamspace,
int searchattrib, uint32 infomask,
uint8 *responsedata)
{
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL);
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
nwp_stat(&(dbe->nwpath), "nw_get_eff_rights");
U16_TO_16(un_nw_rights(&(dbe->nwpath.statb)), responsedata);
responsedata+=2;
result = 2+build_dir_info(dbe, destnamspace, infomask, responsedata);
} else {
XDPRINTF((3, 0, "nw_get_eff_rights NOT OK result=-0x%x",
-result));
}
return(result);
}
static int nw_init_search(int namespace,
NW_HPATH *nwp,
uint8 *pathes,
@ -790,7 +952,7 @@ static int get_add_new_entry(DIR_BASE_ENTRY *qbe, int namespace,
}
static int namespace_fn_match(uint8 *s, uint8 *p, int namespace)
/* for other namespaces than DOS */
/* for other namespaces than DOS + OS2 */
{
int pc, sc;
uint state = 0;
@ -880,18 +1042,30 @@ static int namespace_fn_match(uint8 *s, uint8 *p, int namespace)
int nw_search_file_dir(int namespace, int datastream,
uint32 searchattrib, uint32 infomask,
int volume, uint32 basehandle, uint32 sequence,
int len, uint8 *path, uint8 *responsedata)
uint32 searchattrib, uint32 infomask, int *count,
int volume, uint32 basehandle, uint32 *sequence,
int len, uint8 *path, uint8 *info, int *perhaps_more)
{
int result = find_base_entry(volume, basehandle);
static uint32 saved_sequence=0L;
int max_counts = *count;
int found = 0;
int result = find_base_entry(volume, basehandle);
*perhaps_more = 0;
*count = 0;
if (len > 255) return(-0x9c); /* wrong path */
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT));
ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258);
if (NULL != (ds->fdir = opendir(ds->unixname)) ) {
uint8 entry[257];
uint8 *pe=entry;
int have_wild=0;
int inode_search=0;
uint8 *is_ap=NULL; /* one after point */
struct dirent *dirbuff;
struct stat statb;
int dest_entry=-1;
@ -899,13 +1073,40 @@ int nw_search_file_dir(int namespace, int datastream,
ds->kpath = ds->unixname+strlen(ds->unixname);
*(ds->kpath) = '/';
*(++(ds->kpath)) = '\0';
if (sequence == MAX_U32)
sequence=0L;
if (sequence)
seekdir(ds->fdir, sequence);
if (*sequence == MAX_U32) {
saved_sequence=0L;
*sequence=0L;
}
#if 0
if (saved_sequence) {
seekdir(ds->fdir, saved_sequence);
saved_sequence=0L;
} else
#endif
if (*sequence)
seekdir(ds->fdir, *sequence);
dbe->locked++;
strmaxcpy(entry, path, min(255, len));
while (len--) {
uint8 c=*path++;
*pe++=c;
if (!have_wild) {
if (c==0xff) {
if (*path == '?' || *path == '*'
|| *path == 0xae || *path == 0xbf || *path==0xaa)
have_wild++;
} else if (c == '.') is_ap=pe;
}
}
*pe='\0';
if (!have_wild && is_ap && pe - is_ap == 3 && *is_ap== '_'
&& *(is_ap+1) == '_' && *(is_ap+2) == '_') {
*(is_ap -1) = '\0';
inode_search=atoi(entry);
*(is_ap -1) = '.';
}
if ( (namespace == NAME_DOS || namespace == NAME_OS2)
&& !(vol_options & VOL_OPTION_IGNCASE) ) {
@ -916,30 +1117,31 @@ int nw_search_file_dir(int namespace, int datastream,
}
}
XDPRINTF((5,0,"nw_search_file_dir namspace=%d, searchpath='%s'",
namespace, entry));
XDPRINTF((5,0,"nw_s_f_d namsp=%d,sequence=%d, search='%s'",
namespace, *sequence, entry ));
while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){
uint8 *name=(uint8*)(dirbuff->d_name);
if (dirbuff->d_ino && strlen((char*)name) < 256) {
int flag;
XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name));
if (namespace == NAME_DOS) {
flag = (*name != '.' && fn_dos_match(name, entry, vol_options));
} else if (namespace == NAME_OS2) {
flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' ))
&& fn_os2_match(name, entry, vol_options);
} else {
flag = (!strcmp(name, entry)
|| namespace_fn_match(name, entry, namespace));
}
if (!inode_search) {
if (namespace == NAME_DOS) {
flag = (*name != '.' && fn_dos_match(name, entry, vol_options));
} else if (namespace == NAME_OS2) {
flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' ))
&& fn_os2_match(name, entry, vol_options);
} else {
flag = (!strcmp(name, entry)
|| namespace_fn_match(name, entry, namespace));
}
} else
flag = (dirbuff->d_ino == inode_search);
if (flag) {
strcpy(ds->kpath, name);
XDPRINTF((5,0,"nw_search_file_dir Name found=%s unixname=%s",
name, ds->unixname));
if (!stat(ds->unixname, &statb)) {
flag= (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL;
flag = (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL;
if (!flag) {
if (S_ISDIR(statb.st_mode))
flag=(searchattrib & FILE_ATTR_DIR);
@ -947,11 +1149,23 @@ int nw_search_file_dir(int namespace, int datastream,
flag = !(searchattrib & FILE_ATTR_DIR);
}
if (flag) {
strcpy(entry, name);
if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1)
break;
else {
XDPRINTF((1, 0, "nw_search_file_dir:Cannot add entry '%s'", entry));
if (!found) {
strcpy(entry, name);
if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) {
found++;
#if 0
if (max_counts > 1) {
saved_sequence = (uint32)telldir(ds->fdir);
/* for next turn */
} else
#endif
break;
} else {
XDPRINTF((1, 0, "nw_search_file_dir:Cannot add entry '%s'", entry));
}
} else {
found++;
break;
}
} else {
XDPRINTF((10, 0, "type = %s not ok searchattrib=0x%x",
@ -970,20 +1184,26 @@ int nw_search_file_dir(int namespace, int datastream,
if (dest_entry > -1) {
DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry];
(void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir");
*responsedata = (uint8) volume;
responsedata++;
U32_TO_32(basehandle, responsedata);
responsedata+=4;
U32_TO_32((uint32)telldir(ds->fdir), responsedata);
responsedata+=4;
*responsedata = (uint8) 0; /* reserved */
responsedata++;
result = 10 +
build_dir_info(dest_dbe,
infomask|INFO_MSK_NAME_SPACE_INFO,
responsedata);
} else
#if 0
if (saved_sequence)
*sequence= saved_sequence;
else
#endif
*sequence= (uint32)telldir(ds->fdir);
/* if (found < 2) saved_sequence=0L; */
result = build_dir_info(dest_dbe, datastream,
infomask |INFO_MSK_NAME_SPACE_INFO,
info);
*count=1;
#if 0
*perhaps_more=(found==2) ? 0xff : 0;
#else
*perhaps_more=(have_wild) ? 0xff : 0;
#endif
} else {
saved_sequence=0L;
result=-0xff; /* no files matching */
}
dbe->locked=0;
closedir(ds->fdir);
} /* if NULL != ds->fdir */
@ -993,13 +1213,15 @@ int nw_search_file_dir(int namespace, int datastream,
return(result);
}
static int nw_open_creat_file_or_dir(int namespace,
static int nw_open_creat_file_or_dir(
int namespace,
int opencreatmode,
int attrib, uint32 infomask,
uint32 creatattrib,
int access_rights,
NW_HPATH *nwp, uint8 *pathes,
uint8 *responsedata)
uint8 *responsedata,
int task)
{
int result = build_base(namespace, nwp, pathes, 0, NULL);
int exist = result;
@ -1030,24 +1252,29 @@ static int nw_open_creat_file_or_dir(int namespace,
#endif
creatmode = 1;
}
if ((result = file_creat_open(dbe->nwpath.volume,
nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb),
attrib, access_rights, creatmode)) > -1) {
attrib, access_rights, creatmode, task)) > -1) {
fhandle = (uint32) result;
#if 0
actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */
#endif
if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE))
actionresult |= OPC_ACTION_REPLACE; /* FILE REPLACED */
}
} else result=-0xff;
} else if (exist > -1) result=-0x84;
} else
result=-0xff;
} else if
(exist > -1) result=-0x84;
if (result > -1) {
U32_TO_BE32(fhandle, responsedata);
responsedata += 4;
*responsedata =(uint8) actionresult;
/* responsedata++ ; */
*responsedata =(uint8) actionresult;
*(responsedata+1) = 0;
responsedata+=2;
result = 6 + build_dir_info(dbe,infomask, responsedata);
result = 6 + build_dir_info(dbe, namespace, infomask, responsedata);
}
}
XDPRINTF((3, 0, "nw_open_creat mode=0x%x, creatattr=0x%x, access=0x%x, attr=0x%x, result=%d",
@ -1099,6 +1326,91 @@ static int nw_alloc_short_dir_handle(int namespace, int hmode,
return(result);
}
static int nw_set_short_dir_handle(int namespace, int desthandle,
NW_HPATH *nwp, int task)
{
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL);
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
result=alter_dir_handle(desthandle,
dbe->nwpath.volume, dbe->nwpath.path,
dbe->nwpath.statb.st_ino, task);
} else result=-0x9c; /* wrong path */
}
return((result > 0) ? 0 : result);
}
static int nw_get_full_path_cookies(int namespace,
int destnamspace,
NW_HPATH *nwp, int *cookieflags,
uint32 *cookie1, uint32 *cookie2,
int *components, uint8 *componentpath)
/* SIMPLE IMPLEMENTATION, needs more work !!!! */
{
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL);
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
uint8 *p = componentpath;
uint8 *lastpp = dbe->nwpath.path+strlen(dbe->nwpath.path);
int len=0;
int k=0;
int done=(lastpp==dbe->nwpath.path ||
(lastpp==dbe->nwpath.path+1 && *(dbe->nwpath.path)== '/' ));
int l;
if (*cookie1 != MAX_U32 || *cookie2 != MAX_U32)
return(-0xff);
if (strlen(dbe->nwpath.path) > 256)
return(-0xfb); /* we do support 'short' pathnames only */
while (!done) {
uint8 *pp=lastpp;
while (pp > dbe->nwpath.path && *--pp !='/');;
if (*pp == '/') {
if (pp < dbe->nwpath.path + 2) ++done;
pp++;
l = lastpp-pp;
lastpp = pp-1;
} else {
done++;
l = lastpp-pp;
}
if (l > 255)
return(-0xff);
else if (l > 0) {
len+=(l+1);
*(p++) = (uint8)l;
memcpy(p, pp, l);
*(p+l)='\0';
k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
p+=l;
} else {
XDPRINTF((1, 0, "component=%d, l=%d", k ,l));
}
}
/* now as last element the volume */
l=strlen(nw_volumes[dbe->nwpath.volume].sysname);
len+=(l+1);
*(p++) = (uint8)l;
memcpy(p, nw_volumes[dbe->nwpath.volume].sysname, l);
*(p+l)='\0';
k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
if (len > 400)
return(-0xff); /* we support only 'short' pathnames */
*components = k;
*cookieflags = (S_ISDIR(dbe->nwpath.statb.st_mode)) ? 0 : 1;
*cookie1 = 0;
*cookie2 = MAX_U32; /* no more cookies */
return(len);
}
return(result);
}
static int nw_rename_file_dir(int namespace,
NW_HPATH *nwps, uint8 *pathes_s,
NW_HPATH *nwpd, uint8 *pathes_d,
@ -1201,7 +1513,7 @@ static int nw_modify_file_dir(int namespace,
do_utime++;
}
if (do_utime) {
XDPRINTF((5, 0, "modify datetime 2=%2x,%2x,%2x,%2x",
XDPRINTF((5, 0, "modify datetime 2=%2x,%2x,%2x,%2x",
(int) *datetime,
(int) *(datetime+1),
(int) *(datetime+2),
@ -1228,7 +1540,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
case 0x01 : /* open creat file or subdir */
{
/* NW PATH STRUC */
int opencreatmode = *(p+1);
int opencreatmode = (int) *(p+1);
int attrib = (int) GET_16(p+2); /* LOW-HI */
uint32 infomask = GET_32(p+4); /* LOW-HI */
uint32 creatattrib = GET_32(p+8);
@ -1237,7 +1549,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
memcpy(&nwpathstruct, p+14, sizeof(nwpathstruct));
result = nw_open_creat_file_or_dir(namespace, opencreatmode,
attrib, infomask, creatattrib, access_rights,
&nwpathstruct, p+21, responsedata);
&nwpathstruct, p+21, responsedata, task);
}
break;
@ -1256,6 +1568,12 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
case 0x03 : /* Search for File or DIR */
{
struct OUTPUT {
uint8 volume;
uint8 basehandle[4];
uint8 sequence[4];
uint8 reserved;
} *xdata= (struct OUTPUT*)responsedata;
/* NW PATH STRUC */
int datastream = (int) *(p+1);
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
@ -1265,10 +1583,21 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
uint32 sequence = GET_32(p+13); /* LOW-HI */
int len = *(p+17);
uint8 *path = p+18;
result = nw_search_file_dir(namespace, datastream,
searchattrib, infomask,
volume, basehandle, sequence,
len, path, responsedata);
int count = 1;
int more_entries;
result = nw_search_file_dir(namespace, namespace /*datastream*/,
searchattrib, infomask, &count,
volume, basehandle, &sequence,
len, path,
responsedata+sizeof(struct OUTPUT),
&more_entries);
if (result > -1) {
xdata->volume = (uint8)volume;
U32_TO_32(basehandle, xdata->basehandle);
U32_TO_32(sequence, xdata->sequence);
xdata->reserved = (uint8) 0;
result+=sizeof(struct OUTPUT);
}
}
break;
@ -1290,7 +1619,10 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
case 0x06 : /* Obtain File or Subdir Info */
{
int destnamspace = (int) p+1;
#if 0
static int code = 0;
#endif
int destnamspace = (int) *(p+1);
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
uint32 infomask = GET_32(p+4); /* LOW-HI */
NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8);
@ -1298,6 +1630,19 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
destnamspace,
searchattrib, infomask,
responsedata);
#if 0
if (result < 0) {
/* Unix Client errormessages */
/* there exist *NO* result to force client to use new */
/* basehandles :-(( */
/* most are -> IO/Error */
/* -0x9c; -> no such file or dir */
/* -0xfb; -> Protokoll Error */
/* -0xff; -> no such file or dir */
if (code < 0xff) result=-(++code);
else result=-0xfe;
}
#endif
}
break;
@ -1325,10 +1670,11 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
break;
case 0x09 : /* Set short Dir Handle*/
{
{ /* nw32client needs it */
int desthandle = (int)*(p+2);
NW_HPATH *nwp = (NW_HPATH *)(p+4);
result = nw_set_short_dir_handle(namespace, desthandle, nwp, task);
/* NO REPLY Packet */
}
break;
@ -1353,6 +1699,43 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
}
break;
case 0x14 : /* Search for File or Subdir Set */
/* SIMPLE IMPLEMENTATION, needs more work !!!! */
{
struct OUTPUT {
uint8 volume;
uint8 basehandle[4];
uint8 sequence[4];
uint8 more_entries; /* NW4.1 (UNIX) says 0xff here */
uint8 count[2]; /* count of entries */
} *xdata= (struct OUTPUT*)responsedata;
int datastream = (int) *(p+1);
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
uint32 infomask = GET_32(p+4); /* LOW-HI */
int count = (int)GET_16(p+8);
int volume = *(p+10);
uint32 basehandle = GET_32(p+11); /* LOW-HI */
uint32 sequence = GET_32(p+15); /* LOW-HI */
int len = *(p+19);
uint8 *path = p+20;
int more_entries;
result = nw_search_file_dir(namespace, namespace /*datastream*/,
searchattrib, infomask, &count,
volume, basehandle, &sequence,
len, path,
responsedata+sizeof(struct OUTPUT),
&more_entries);
if (result > -1) {
xdata->volume = (uint8)volume;
U32_TO_32(basehandle, xdata->basehandle);
U32_TO_32(sequence, xdata->sequence);
xdata->more_entries = (uint8) more_entries;
U16_TO_16(count, xdata->count);
result+=sizeof(struct OUTPUT);
}
}
break;
case 0x15 : /* Get Path String from short dir new */
{
int dir_handle=(int) *(p+1);
@ -1410,14 +1793,48 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
}
break;
case 0x1c : /* GetFullPathString new*/
{
case 0x1c : /* GetFullPathString new*/
{ /* nw32 client needs it */
/* SIMPLE IMPLEMENTATION, needs more work !!!! */
int destnamspace = (int)*(p+1);
int cookieflags = (int)GET_16(p+2);
uint32 cookie1 = GET_32(p+4);
uint32 cookie2 = GET_32(p+8);
NW_HPATH *nwpathstruct = (NW_HPATH *)(p+12);
int components;
struct OUTPUT {
uint8 cookieflags[2]; /* 0 = DIR; 1 = FILE */
uint8 cookie1[4];
uint8 cookie2[4];
uint8 pathsize[2]; /* complete components size */
uint8 pathcount[2]; /* component counts */
} *xdata= (struct OUTPUT*)responsedata;
result = nw_get_full_path_cookies(namespace, destnamspace,
nwpathstruct,
&cookieflags, &cookie1, &cookie2, &components,
responsedata+sizeof(struct OUTPUT));
if (result > -1) {
U16_TO_16(cookieflags, xdata->cookieflags);
U32_TO_32(cookie1, xdata->cookie1);
U32_TO_32(cookie2, xdata->cookie2);
U16_TO_16(result, xdata->pathsize);
U16_TO_16(components, xdata->pathcount);
result+=sizeof(struct OUTPUT);
}
}
break;
case 0x1d : /* GetEffDirRights new */
{
int destnamspace = (int) *(p+1);
int searchattrib = (int) GET_16(p+2); /* LOW-HI */
uint32 infomask = GET_32(p+4); /* LOW-HI */
NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8);
result = nw_get_eff_rights(namespace, nwpathstruct,
destnamspace,
searchattrib, infomask,
responsedata);
}
break;
@ -1426,46 +1843,6 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task)
return(result);
}
static void build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname)
{
uint8 *ss=e->nwpath.fn;
int len=0;
int pf=0;
int is_ok=1;
int options=get_volume_options(e->nwpath.volume, 1);
for (; *ss; ss++){
if (*ss == '.') {
if (pf++) { /* no 2. point */
is_ok=0;
break;
}
len=0;
} else {
++len;
if ((pf && len > 3) || len > 8) {
is_ok=0;
break;
}
if (!(options & VOL_OPTION_IGNCASE)){
if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */
if (*ss >= 'A' && *ss <= 'Z') {
is_ok=0;
break;
}
} else { /* only upshift chars */
if (*ss >= 'a' && *ss <= 'z') {
is_ok=0;
break;
}
}
}
}
}
if (is_ok)
strcpy(fname, e->nwpath.fn);
else
sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino);
}
int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata)
@ -1484,7 +1861,7 @@ int get_namespace_dir_entry(int volume, uint32 basehandle,
#else
U32_TO_32(name_2_base(&(e->nwpath), NAME_DOS, 1), scif->searchsequence);
#endif
build_dos_name(e, fname);
(void)build_dos_name(e, fname);
if (S_ISDIR(e->nwpath.statb.st_mode)) {
get_dos_dir_attrib(&(scif->u.d), &e->nwpath.statb,
e->nwpath.volume, fname);

View File

@ -1,4 +1,4 @@
/* namspace.h 07-Feb-96 : NameSpace Services, mars_nwe */
/* namspace.h 09-Nov-96 : NameSpace Services, mars_nwe */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
@ -32,7 +32,11 @@ typedef struct {
uint8 base[4]; /* Base or short Handle, handle is base[0] !! */
uint8 flag; /* 0=handle, 1=base, 0xff=not path nor handle */
uint8 components; /* nmbrs of pathes, components */
uint8 pathes[1]; /* form len+name */
uint8 pathes[1]; /* form len+name (like Pascal) */
/* ATTENTION
* a pathlen of 0 means '..' (cd dir ..) !!
* first seen with Novell client32
*/
} NW_HPATH;
typedef struct {
@ -65,10 +69,6 @@ typedef struct {
#define INFO_MSK_DIR_ENTRY_INFO 0x00000400
#define INFO_MSK_RIGHTS_INFO 0x00000800
/* File Attributes */
#define FILE_ATTR_NORMAL 0x00000000
#define FILE_ATTR_DIR 0x00000010
#define FILE_ATTR_SHARE 0x00000080
/* Search Attributes */
#define W_SEARCH_ATTR_DIR 0x00008000

View File

@ -1,4 +1,4 @@
/* ncpserv.c 20-Mar-96 */
/* ncpserv.c 01-Nov-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -119,34 +119,11 @@ static void write_to_nwserv(int what, int connection, int mode,
static int open_ipx_sockets(void)
{
struct t_bind bind;
ncp_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ncp_fd < 0) {
t_error("t_open !Ok");
ncp_fd = open_ipx_socket(&my_addr, SOCK_NCP);
if (ncp_fd < 0)
return(-1);
}
U16_TO_BE16(SOCK_NCP, my_addr.sock); /* NCP_SOCKET */
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_addr;
bind.qlen = 0; /* ever 0 */
if (t_bind(ncp_fd, &bind, &bind) < 0){
t_error("t_bind in open_ipx_sockets !OK");
close(ncp_fd);
return(-1);
}
#if USE_PERMANENT_OUT_SOCKET
ipx_out_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ipx_out_fd > -1) {
U16_TO_BE16(0, my_addr.sock); /* dynamic socket */
if (t_bind(ipx_out_fd, &bind, &bind) < 0) {
if (nw_debug) t_error("2. t_bind in open_ipx_sockets !OK");
t_close(ipx_out_fd);
ipx_out_fd = -1;
}
} else {
if (nw_debug) t_error("2. t_open !Ok");
}
ipx_out_fd = open_ipx_socket(NULL, 0);
#endif
return(0);
}
@ -479,6 +456,9 @@ static int handle_ctrl(void)
if (data_len == sizeof(int)) {
XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd->owndata.d.size));
#if 1
(void)send_own_reply(ipx_out_fd, 0, ipxd->owndata.h.sequence, &from_addr);
#endif
switch (what) {
case 0x5555 : /* clear_connection, from wdog process */
if (sizeof (int) ==
@ -517,9 +497,14 @@ static void handle_ncp_request(void)
XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr)));
if ((type = GET_BE16(ncprequest->type)) == 0x2222
|| type == 0x5555) {
int connection = (int)ncprequest->connection;
XDPRINTF((10,0, "GOT 0x%x in NCPSERV connection=%d", type, connection));
#if 0
ncp_response(0x9999, ncprequest->sequence,
connection, ncprequest->task,
0x0, 0, 0);
#endif
if ( connection > 0 && connection <= anz_connect) {
CONNECTION *c = &(connections[connection-1]);
@ -537,7 +522,8 @@ static void handle_ncp_request(void)
&& !c->retry++) {
/* perhaps nwconn is busy */
ncp_response(0x9999, ncprequest->sequence,
connection, 0, 0x0, 0, 0);
connection, ncprequest->task,
0x0, 0, 0);
XDPRINTF((2, 0, "Send Request being serviced to connection:%d", connection));
return;
}
@ -561,9 +547,7 @@ static void handle_ncp_request(void)
if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence)
#endif
{
#if 1
clear_connection(connection);
#endif
ncp_response(0x3333,
ncprequest->sequence,
connection,
@ -589,6 +573,7 @@ static void handle_ncp_request(void)
type, ncprequest->connection,
anz_connect));
}
if (type == 0x5555 || (type == 0x2222 && ncprequest->function == 0x19)) {
compl = 0;
cstat = 0;
@ -598,7 +583,7 @@ static void handle_ncp_request(void)
}
ncp_response(0x3333, ncprequest->sequence,
ncprequest->connection,
(type== 0x5555) ? 0 : 1, /* task */
(type== 0x5555) ? 0 : ncprequest->task, /* task */
compl, /* completition */
cstat, /* conn status */
0);
@ -688,6 +673,7 @@ int main(int argc, char *argv[])
#ifdef LINUX
set_emu_tli();
#endif
if (open_ipx_sockets()) {
errorp(1, "open_ipx_sockets", NULL);
return(1);

53
net.h
View File

@ -1,4 +1,4 @@
/* net.h 03-May-96 */
/* net.h 25-Oct-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
@ -82,23 +82,21 @@ extern int errno;
*( (uint8*) (b) ) = *( ((uint8*) (&a)) +1); \
*( ((uint8*) (b)) +1) = *( (uint8*) (&a)); }
#if 0
/* I don't know anymore why I did coded it in this form */
#define X_U32_TO_BE32(u, ar) { uint32 a= (uint32)(u); uint8 *b= ((uint8*)(ar))+3; \
*b-- = (uint8)a; a >>= 8; \
*b-- = (uint8)a; a >>= 8; \
*b-- = (uint8)a; a >>= 8; \
*b = (uint8)a; }
#else
#define X_U32_TO_BE32(u, b) { uint32 a=(uint32)(u); \
*( (uint8*) (b)) = *( ((uint8*) (&a))+3); \
*( ((uint8*) (b)) +1) = *( ((uint8*) (&a))+2); \
*( ((uint8*) (b)) +2) = *( ((uint8*) (&a))+1); \
*( ((uint8*) (b)) +3) = *( (uint8*) (&a)); }
#endif
#define X_U16_TO_16(u, b) { uint16 a=(uint16)(u); memcpy(b, &a, 2); }
#define X_U32_TO_32(u, b) { uint32 a=(uint32)(u); memcpy(b, &a, 4); }
#define X_U16_TO_16(u, b) { uint16 a=(uint16)(u); \
((uint8*)b)[0] = ((uint8*)&a)[0]; \
((uint8*)b)[1] = ((uint8*)&a)[1]; }
#define X_U32_TO_32(u, b) { uint32 a=(uint32)(u); \
((uint8*)b)[0] = ((uint8*)&a)[0]; \
((uint8*)b)[1] = ((uint8*)&a)[1]; \
((uint8*)b)[2] = ((uint8*)&a)[2]; \
((uint8*)b)[3] = ((uint8*)&a)[3]; }
#define GET_BE16(b) ( (int) *(((uint8*)(b))+1) \
| ( ( (int) *( (uint8*)(b) ) << 8) ) )
@ -236,10 +234,21 @@ extern int errno;
# define MAX_NW_SERVERS MAX_NW_ROUTES
#endif
#ifndef HANDLE_ALL_SAP_TYPS
# define HANDLE_ALL_SAP_TYPS 0
#endif
#if IPX_DATA_GR_546
# define IPX_MAX_DATA 1058
# if IPX_DATA_GR_546 == 2
# define IPX_MAX_DATA 1470
# define RW_BUFFERSIZE 1444
# else
# define IPX_MAX_DATA 1058
# define RW_BUFFERSIZE 1024
# endif
#else
# define IPX_MAX_DATA 546
# define IPX_MAX_DATA 546
# define RW_BUFFERSIZE 512
#endif
#ifndef SOCK_EXTERN
@ -366,15 +375,22 @@ typedef union {
uint8 function; /* Function */
} ncprequest;
struct S_OWN_DATA {
uint8 type[2]; /* 0xeeee */
uint8 sequence;
uint8 connection;
struct {
uint8 type[2]; /* 0xeeee */
uint8 sequence;
uint8 reserved; /* its good for alignement */
} h; /* header */
struct {
int size; /* size of next two entries */
int function;
uint8 data[1];
} d;
} owndata;
struct S_OWN_REPLY {
uint8 type[2]; /* 0xefef */
uint8 sequence;
uint8 result; /* perhaps we need it */
} ownreply;
char data[IPX_MAX_DATA];
} IPX_DATA;
@ -389,8 +405,7 @@ typedef struct S_DIAGRESP DIAGRESP;
typedef struct S_NCPRESPONSE NCPRESPONSE;
typedef struct S_NCPREQUEST NCPREQUEST;
typedef struct S_OWN_DATA OWN_DATA;
#define OWN_DATA_IPX_BASE_SIZE 8
typedef struct S_OWN_REPLY OWN_REPLY;
/* SOCKETS */
#define SOCK_AUTO 0x0000 /* Autobound Socket */

158
net1.c
View File

@ -1,4 +1,4 @@
/* net1.c, 20-Mar-96 */
/* net1.c, 26-Oct-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
@ -19,6 +19,9 @@
#include "net.h"
#define MAX_SEND_TRIES 5
#define MAX_WAIT_MSEC 1000 /* 1 sec should be enough */
#if HAVE_TLI
void print_t_info(struct t_info *t)
{
@ -147,12 +150,36 @@ void ipx_addr_to_adr(char *s, ipxAddr_t *p)
(int)p->sock[1]);
}
int open_ipx_socket(ipxAddr_t *addr, int sock_nr)
{
struct t_bind bind;
ipxAddr_t addr_buff;
int fd=t_open("/dev/ipx", O_RDWR, NULL);
if (fd < 0) {
t_error("t_open !Ok");
return(-1);
}
if (NULL == addr)
addr = &addr_buff;
memset(addr, 0, sizeof(ipxAddr_t));
U16_TO_BE16(sock_nr, addr->sock);
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)addr;
bind.qlen = 0;
if (t_bind(fd, &bind, &bind) < 0){
t_error("t_bind,open_ipx_socket");
t_close(fd);
return(-1);
}
return(fd);
}
int send_ipx_data(int fdx, int pack_typ,
int send_ipx_data(int fd, int pack_typ,
int data_len, char *data,
ipxAddr_t *to_addr, char *comment)
{
int fd=fdx;
int fd_is_dyna=0;
int result=0;
struct t_unitdata ud;
uint8 ipx_pack_typ = (uint8) pack_typ;
@ -168,34 +195,125 @@ int send_ipx_data(int fdx, int pack_typ,
if (comment != NULL) XDPRINTF((2,0,"%s TO: ", comment));
if (nw_debug > 1) print_ipx_addr(to_addr);
if (fd < 0) {
struct t_bind bind;
ipxAddr_t addr;
fd=t_open("/dev/ipx", O_RDWR, NULL);
if (fd < 0) {
t_error("t_open !Ok");
if ((fd=open_ipx_socket(NULL, 0)) < 0)
return(-1);
}
memset(&addr,0, sizeof(ipxAddr_t));
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&addr;
bind.qlen = 0; /* ever */
if (t_bind(fd, &bind, &bind) < 0){
t_error("t_bind in send_ipx_data");
t_close(fd);
return(-1);
}
fd_is_dyna++;
}
if ((result=t_sndudata(fd, &ud)) < 0){
if (nw_debug > 1) t_error("t_sndudata !OK");
}
if (fdx < 0 && fd > -1) {
if (fd_is_dyna) {
t_unbind(fd);
t_close(fd);
}
return(result);
}
int receive_ipx_data(int fd, int *pack_typ, IPX_DATA *d,
ipxAddr_t *fromaddr, int waitmsec)
{
int result=-1;
if (waitmsec) {
struct pollfd polls[1];
polls[0].fd = fd;
polls[0].events = POLLIN|POLLPRI;
polls[0].revents = 0;
if (1 == poll(polls, 1, waitmsec))
waitmsec=0;
}
if (!waitmsec) {
struct t_unitdata ud;
uint8 ipx_pack_typ;
int flags = 0;
ud.opt.len = sizeof(ipx_pack_typ);
ud.opt.maxlen = sizeof(ipx_pack_typ);
ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual typ */
ud.addr.len = sizeof(ipxAddr_t);
ud.addr.maxlen = sizeof(ipxAddr_t);
ud.addr.buf = (char*)fromaddr;
ud.udata.len = IPX_MAX_DATA;
ud.udata.maxlen = IPX_MAX_DATA;
ud.udata.buf = (char*)d;
if (t_rcvudata(fd, &ud, &flags) < 0){
struct t_uderr uderr;
ipxAddr_t erradr;
uint8 err_pack_typ;
uderr.addr.len = sizeof(ipxAddr_t);
uderr.addr.maxlen = sizeof(ipxAddr_t);
uderr.addr.buf = (char*)&erradr;
uderr.opt.len = sizeof(err_pack_typ);
uderr.opt.maxlen = sizeof(err_pack_typ);
uderr.opt.buf = (char*)&err_pack_typ; /* get actual typ */
ud.addr.buf = (char*)&fromaddr;
t_rcvuderr(fd, &uderr);
XDPRINTF((2, 0, "Error from %s, Code = 0x%lx", visable_ipx_adr(&erradr), uderr.error));
if (nw_debug)
t_error("t_rcvudata !OK");
result = -1;
} else {
if (pack_typ)
*pack_typ=(int)ipx_pack_typ;
result=ud.udata.len;
}
}
return(result);
}
int send_own_data(int fd, IPX_DATA *d, ipxAddr_t *toaddr)
/* returns < 0 if senderror or functionresultcode > = 0 */
{
static int lastsequence=0;
int result = -1;
int tries = 0;
int sendsize = d->owndata.d.size+sizeof(d->owndata.d.size)+
sizeof(d->owndata.h);
d->owndata.h.type[0] = 0xee;
d->owndata.h.type[1] = 0xee;
d->owndata.h.sequence = (uint8) ++lastsequence;
d->owndata.h.reserved = 0;
while (tries++ < MAX_SEND_TRIES && result < 0) {
result=send_ipx_data(fd, 17, sendsize, (char*)d,
toaddr, "send_own_data");
if (result > -1) {
int packet_typ;
IPX_DATA ipxd;
ipxAddr_t fromaddr;
result=receive_ipx_data(fd, &packet_typ, &ipxd, &fromaddr,
MAX_WAIT_MSEC);
XDPRINTF((2, 0, "receive_ipx_data, result=%d, typ=0x%x%x, sequence=%d",
result,
(int)ipxd.ownreply.type[0],
(int)ipxd.ownreply.type[1],
(int)ipxd.ownreply.sequence ));
if (sizeof(OWN_REPLY) == result &&
ipxd.ownreply.type[0] == 0xef &&
ipxd.ownreply.type[1] == 0xef &&
/* !memcmp(&fromaddr, toaddr, sizeof(ipxAddr_t)) && */
ipxd.ownreply.sequence == d->owndata.h.sequence) {
result = (int)ipxd.ownreply.result;
} else
result=-1;
}
} /* while */
return(result);
}
int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr)
{
IPX_DATA ipxd;
IPX_DATA *d=&ipxd;
d->ownreply.type[0] = 0xef;
d->ownreply.type[1] = 0xef;
d->ownreply.sequence = (uint8) sequence;
d->ownreply.result = result;
return(send_ipx_data(fd, 17, sizeof(OWN_REPLY),
(char*)d, toaddr, "send_own_reply"));
}
#if 0
int get_ipx_addr(ipxAddr_t *addr)
{

10
net1.h
View File

@ -1,4 +1,4 @@
/* net1.h 20-Mar-96 */
/* net1.h 25-Oct-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
@ -34,10 +34,18 @@ extern void print_sip_data(SIP *sip);
extern void adr_to_ipx_addr(ipxAddr_t *p, char *s);
extern void ipx_addr_to_adr(char *s, ipxAddr_t *p);
extern int open_ipx_socket(ipxAddr_t *addr, int sock_nr);
extern int send_ipx_data(int fd, int pack_typ,
int data_len, char *data,
ipxAddr_t *to_addr, char *comment);
extern int receive_ipx_data(int fd, int *pack_typ, IPX_DATA *d,
ipxAddr_t *fromaddr, int waitmsec);
extern int send_own_data(int fd, IPX_DATA *d, ipxAddr_t *toaddr);
extern int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr);
extern int get_ipx_addr(ipxAddr_t *addr);
#endif

View File

@ -1,5 +1,5 @@
/* nwbind.c */
#define REVISION_DATE "04-Oct-96"
#define REVISION_DATE "01-Nov-96"
/* NCP Bindery SUB-SERVER */
/* authentification and some message handling */
@ -64,44 +64,6 @@ static void write_to_nwserv(int what, int connection, int mode,
#define nwserv_down_server() \
write_to_nwserv(0xffff, 0, 0, NULL, 0)
static int open_ipx_sockets(void)
{
struct t_bind bind;
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_addr;
bind.qlen = 0; /* immer */
#if 0
ncp_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ncp_fd < 0) {
t_error("t_open !Ok");
return(-1);
}
U16_TO_BE16(SOCK_BINDERY, my_addr.sock);
if (t_bind(ncp_fd, &bind, &bind) < 0){
t_error("t_bind in open_ipx_sockets !OK");
close(ncp_fd);
return(-1);
}
#endif
#if USE_PERMANENT_OUT_SOCKET
ipx_out_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ipx_out_fd > -1) {
U16_TO_BE16(SOCK_AUTO, my_addr.sock); /* dynamic socket */
if (t_bind(ipx_out_fd, &bind, &bind) < 0) {
if (nw_debug) t_error("2. t_bind in open_ipx_sockets !OK");
t_close(ipx_out_fd);
ipx_out_fd = -1;
}
} else {
if (nw_debug) t_error("2. t_open !Ok");
}
#endif
return(0);
}
typedef struct {
ipxAddr_t client_adr; /* address remote client */
uint32 object_id; /* logged object */
@ -1280,6 +1242,7 @@ static void handle_fxx(int gelen, int func)
U16_TO_BE16(0x3333, ncpresponse->type);
ncpresponse->sequence = ncprequest->sequence;
ncpresponse->task = ncprequest->task;
ncpresponse->connection = ncprequest->connection;
ncpresponse->reserved = 0;
ncpresponse->completition = completition;
@ -1352,7 +1315,7 @@ static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size)
return(size);
}
static void handle_ctrl(void)
static void handle_ctrl()
/* reads packets from nwserv/ncpserv */
{
IPX_DATA ipxd;
@ -1364,8 +1327,10 @@ static void handle_ctrl(void)
if (data_len == sizeof(int)) {
XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d",
what, ipxd.owndata.d.size));
switch (what) {
(void)send_own_reply(ipx_out_fd, 0, ipxd.owndata.h.sequence, &from_addr);
switch (what) {
case 0x2222 : /* insert connection */
if (sizeof (int) ==
xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) {
@ -1409,9 +1374,9 @@ static void handle_ctrl(void)
if (sizeof(int) == data_len && conn == what)
sent_down_message();
break;
default : break;
} /* switch */
} else {
errorp(1, "handle_ctrl", "wrong data len=%d", data_len);
}
@ -1461,11 +1426,9 @@ int main(int argc, char *argv[])
set_emu_tli();
#endif
if (open_ipx_sockets()) {
errorp(1, "open_ipx_sockets", NULL);
exit(1);
}
#if USE_PERMANENT_OUT_SOCKET
ipx_out_fd=open_ipx_socket(NULL, 0);
#endif
XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s",
(ipx_out_fd > -1) ? "enabled" : "disabled"));
@ -1509,12 +1472,11 @@ int main(int argc, char *argv[])
&& IPXCMPNODE(from_addr.node, my_addr.node)
&& IPXCMPNET (from_addr.net, my_addr.net)) {
/* comes from nwserv, i hope :) */
handle_ctrl();
} else {
XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x",
(int) GET_BE16(ncprequest->type), (int) ncprequest->function));
XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x from %s",
(int) GET_BE16(ncprequest->type),
(int) ncprequest->function, visable_ipx_adr(&from_addr) ));
}
}
if (got_sig == SIGHUP) {

View File

@ -1,4 +1,4 @@
/* nwconn.c 03-Oct-96 */
/* nwconn.c 06-Nov-96 */
/* one process / connection */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -47,6 +47,7 @@ static uint8 readbuff[IPX_MAX_DATA];
static uint8 saved_readbuff[IPX_MAX_DATA];
static int saved_sequence=-1;
static int rw_buffer_size = 512; /* default */
static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff;
static uint8 *requestdata = readbuff + sizeof(NCPREQUEST);
@ -56,10 +57,11 @@ static int sock_echo =-1;
static int req_printed=0;
static int ncp_response(int sequence,
static int ncp_response(int sequence, int task,
int completition, int data_len)
{
ncpresponse->sequence = (uint8) sequence;
ncpresponse->task = (uint8) task;
ncpresponse->completition = (uint8) completition;
ncpresponse->reserved = (uint8) 0;
last_sequence = sequence;
@ -326,7 +328,7 @@ static int handle_ncp_serv(void)
xdata->volume = (uint8) result;
data_len = 1;
} else completition = (uint8) -result;
} else if (*p == 0x6){ /* Get Volume Name von 0 .. 31 */
} else if (*p == 0x6){ /* Get Volume Name from 0 .. 31 */
/******** Get Volume Name ***************/
struct XDATA {
uint8 namelen;
@ -447,7 +449,7 @@ static int handle_ncp_serv(void)
}
}
data_len = sizeof(struct XDATA);
XDPRINTF((5,0,"GIVE VOLUME INFO von :%s:", xdata->name));
XDPRINTF((5,0,"GIVE VOLUME INFO from :%s:", xdata->name));
result = 0;
}
}
@ -855,7 +857,7 @@ static int handle_ncp_serv(void)
uint8 size[4];
uint8 weisnicht[2]; /* lock timeout ??? */
} *input = (struct INPUT *)ncprequest;
int fhandle = GET_BE32(input->fhandle);
int fhandle = GET_BE32 (input->fhandle);
int offset = GET_BE32(input->offset);
int size = GET_BE32(input->size);
completition = (uint8)(-nw_lock_datei(fhandle,
@ -865,17 +867,13 @@ static int handle_ncp_serv(void)
break;
case 0x21 : { /* Negotiate Buffer Size, Packetsize */
int wantsize = GET_BE16((uint8*)requestdata);
uint8 *getsize=responsedata;
#if !IPX_DATA_GR_546
wantsize = min(0x200, wantsize);
#else
wantsize = min(0x400, wantsize);
#endif
U16_TO_BE16(wantsize, getsize);
rw_buffer_size = min(RW_BUFFERSIZE,
(int) (GET_BE16((uint8*)requestdata)));
U16_TO_BE16(rw_buffer_size, getsize);
data_len = 2;
XDPRINTF((5,0, "Negotiate Buffer size = 0x%04x,(%d)",
(int) wantsize, (int) wantsize));
(int) rw_buffer_size, (int) rw_buffer_size));
}
break;
@ -931,7 +929,7 @@ static int handle_ncp_serv(void)
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 volume; /* Volume ID */
uint8 dir_id[2]; /* von File Search Init */
uint8 dir_id[2]; /* from File Search Init */
uint8 searchsequence[2]; /* sequence FFFF = first entry */
uint8 search_attrib; /* Attribute */
/* 0 none,
@ -1024,7 +1022,7 @@ static int handle_ncp_serv(void)
input->data, input->len,
&(xdata->fileinfo),
(int)input->attrib,
0x1, 0);
0x1, 0, (int)(ncprequest->task));
if (fhandle > -1){
U32_TO_BE32(fhandle, xdata->fhandle);
@ -1075,7 +1073,8 @@ static int handle_ncp_serv(void)
&(xdata->fileinfo),
(int)input->attribute,
0,
(function==0x43) ? 1 : 2);
(function==0x43) ? 1 : 2,
(int)(ncprequest->task));
if (fhandle > -1){
data_len = sizeof(struct XDATA);
U32_TO_BE32(fhandle, xdata->fhandle);
@ -1189,7 +1188,13 @@ static int handle_ncp_serv(void)
int max_size = GET_BE16(input->max_size);
off_t offset = GET_BE32(input->offset);
int zusatz = (offset & 1) ? 1 : 0;
int size = nw_read_datei(fhandle,
int size;
if (max_size > rw_buffer_size) {
XDPRINTF((1,0, "wanted read=%d byte > %d",
max_size, rw_buffer_size));
size = -0x88; /* we say wrong filehandle */
} else
size = nw_read_datei(fhandle,
xdata->data+zusatz,
max_size,
offset);
@ -1296,7 +1301,8 @@ static int handle_ncp_serv(void)
input->data, input->len,
&(xdata->fileinfo),
(int)input->attrib,
(int)input->access, 0);
(int)input->access, 0,
(int)(ncprequest->task));
if (fhandle > -1){
U32_TO_BE32(fhandle, xdata->fhandle);
@ -1336,6 +1342,7 @@ static int handle_ncp_serv(void)
#ifdef _MAR_TESTS_XX
case 0x5f : { /* ????????????? UNIX Client */
/* a 4.1 Server also do not know this call */
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 unknown[4]; /* 0x10, 0,0,0 */
@ -1418,10 +1425,7 @@ static int handle_ncp_serv(void)
XDPRINTF((0,1, NULL));
}
}
#if 0
ncpresponse->task = ncprequest->task;
#endif
ncp_response(ncprequest->sequence, completition, data_len);
ncp_response(ncprequest->sequence, ncprequest->task, completition, data_len);
nw_debug = org_nw_debug;
return(0);
}
@ -1501,7 +1505,7 @@ static void handle_after_bind()
break;
default : completition = 0xfb;
} /* switch */
ncp_response(ncprequest->sequence, completition, data_len);
ncp_response(ncprequest->sequence, ncprequest->task, completition, data_len);
}
extern int t_errno;
@ -1617,6 +1621,9 @@ int main(int argc, char **argv)
*/
ncpresponse->connect_status = (uint8) 0;
/* new: 01-Nov-96 */
ncpresponse->task = ncprequest->task;
if (fl_get_int) {
if (fl_get_int == 1) get_new_debug();
else if (fl_get_int < 0) break;
@ -1639,8 +1646,9 @@ int main(int argc, char **argv)
if (data_len)
memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len);
ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status;
ncp_response((int)(ncprequest->sequence),
(int)(ncprequest->function), data_len);
ncp_response(ncprequest->sequence,
ncprequest->task,
ncprequest->function, data_len);
}
saved_sequence = -1;
} else { /* this calls I must handle, it is a request */

View File

@ -1247,7 +1247,7 @@ int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr)
}
}
XDPRINTF((1, 0, "No access for Station %s", visable_ipx_adr(client_adr)));
return(-0xff); /* perhaps I find a better result later */
return(-0xdb); /* unauthorized login station */
}
#if 0

121
nwfile.c
View File

@ -1,4 +1,4 @@
/* nwfile.c 29-Sep-96 */
/* nwfile.c 04-Nov-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -39,11 +39,12 @@ void sig_bus_mmap(int rsig)
#endif
static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN];
#define HOFFS 0
static int anz_fhandles=0;
static int new_file_handle(uint8 *unixname)
static int new_file_handle(uint8 *unixname, int task)
{
int rethandle = -1;
int rethandle = HOFFS -1;
FILE_HANDLE *fh=NULL;
while (++rethandle < anz_fhandles) {
FILE_HANDLE *fh=&(file_handles[rethandle]);
@ -62,6 +63,7 @@ static int new_file_handle(uint8 *unixname)
}
}
/* init handle */
fh->task = task;
fh->fd = -2;
fh->offd = 0L;
fh->tmodi = 0L;
@ -76,7 +78,7 @@ static int new_file_handle(uint8 *unixname)
static int free_file_handle(int fhandle)
{
int result=-0x88;
if (fhandle > 0 && (fhandle <= anz_fhandles)) {
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_PIPE_COMMAND) {
@ -105,7 +107,7 @@ static int free_file_handle(int fhandle)
if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) {
/* was last */
anz_fhandles--;
while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1
while (anz_fhandles > HOFFS && file_handles[anz_fhandles-1].fd == -1
&& !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) )
anz_fhandles--;
}
@ -116,14 +118,28 @@ static int free_file_handle(int fhandle)
return(result); /* wrong filehandle */
}
void init_file_module(void)
void init_file_module(int task)
/*
* if task == -1 all handles will be free'd
* else only handles of the task will be free'd
*/
{
int k = 0;
while (k++ < anz_fhandles) free_file_handle(k);
anz_fhandles = 0;
int k = HOFFS;
if (task < 0) {
while (k++ < anz_fhandles)
free_file_handle(k);
anz_fhandles = HOFFS;
} else {
/* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */
while (k++ < anz_fhandles) {
FILE_HANDLE *fh=&(file_handles[k-1]);
if (fh->task == task) {
free_file_handle(k);
}
}
}
}
static int xsetegid(gid_t gid)
{
int result = -1;
@ -141,7 +157,7 @@ static int xsetegid(gid_t gid)
}
int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
int attrib, int access, int creatmode)
int attrib, int access, int creatmode, int task)
/*
* creatmode: 0 = open
* | 1 = creat (ever)
@ -152,8 +168,11 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
*
* access: 0x1=read,
* 0x2=write,
* 0x4=deny read, -> F_WRLCK
* 0x8=deny write -> F_RDLCK
* 0x4=deny read, -> F_WRLCK, no other process can make
* a read or write lock
* can only be used if file is open for writing
* 0x8=deny write -> F_RDLCK, no other process can make a writelock
* can only be used if file is open for reading
* 0x10=SH_COMPAT
*
* 0x09 (O_RDONLY | O_DENYWRITE);
@ -167,9 +186,9 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
*
*/
{
int fhandle = new_file_handle(unixname);
int dowrite = (access & 2) || creatmode;
if (fhandle > 0){
int fhandle = new_file_handle(unixname, task);
int dowrite = ((access & 2) || creatmode) ? 1 : 0;
if (fhandle > HOFFS){
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
int completition = 0; /* first ok */
int voloptions = get_volume_options(volume, 1);
@ -188,9 +207,18 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
if (creatmode & 2) {
XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->fname));
completition = -0x85; /* No Priv */
} else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) )
completition = (creatmode) ? -0x84 : -0x94;
else if (!(acc & R_OK) && !(creatmode & 0x8) )
} else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) ) {
if (!S_ISFIFO(stbuff->st_mode)) {
if (entry8_flags&2 && (acc & R_OK)) {
/* we use strange compatibility modus */
dowrite=0;
XDPRINTF((1, 0, "Uses strange open comp. mode for file `%s`",
fh->fname));
} else
completition = (creatmode) ? -0x84 : -0x94;
} else
completition = (creatmode) ? -0x84 : -0x94;
} else if (!(acc & R_OK) && !(creatmode & 0x8) )
completition = -0x93;
} else if (acc & X_OK) {
/* special Handling for PIPE commands */
@ -260,6 +288,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
if (!dowrite)
stbuff->st_size = 0x7fff0000 | (rand() & 0xffff);
(void)time(&(stbuff->st_mtime));
stbuff->st_atime = stbuff->st_mtime;
if (creatmode & 4)
fh->fh_flags |= FH_DO_NOT_REUSE;
if (did_grpchange)
@ -301,18 +330,18 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
stat(fh->fname, stbuff);
}
} else {
/* 'normal' open of file */
/* ======== 'normal' open of file ================ */
int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY;
if (S_ISFIFO(stbuff->st_mode)){
acm |= O_NONBLOCK;
fh->fh_flags |= FH_IS_PIPE;
if (!dowrite) stbuff->st_size = 0x7fffffff;
(void)time(&(stbuff->st_mtime));
stbuff->st_atime = stbuff->st_mtime;
}
fh->fd = open(fh->fname, acm);
XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",
attrib,access, fh->fname, fhandle));
fh->offd = 0L;
XDPRINTF((5,0, "OPEN FILE:fd=%d, attrib:0x%x, access:0x%x, fh->fname:%s:fhandle=%d",
fh->fd, attrib, access, fh->fname, fhandle));
if (fh->fd < 0)
completition = dowrite ? -0x94 : -0x93;
}
@ -321,9 +350,23 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
if (!(fh->fh_flags & FH_IS_PIPE)) {
/* Not a PIPE */
if ((access & 0x4) || (access & 0x8)) {
/* we use file sharing */
struct flock flockd;
int result;
flockd.l_type = (access & 0x8) ? F_RDLCK : F_WRLCK;
int result = (access & 0x4) ? 1 : 0; /* here for writelock */
#if 0
if (result != dowrite) {
XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes openmode=%s, file=%s",
access, (dowrite) ? "W" : "R", fh->fname));
result = dowrite;
}
#else
if ((!dowrite) && result) {
XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes R-open file=%s",
access, fh->fname));
result = dowrite;
}
#endif
flockd.l_type = (result) ? F_WRLCK : F_RDLCK;
flockd.l_whence = SEEK_SET;
flockd.l_start = 0;
flockd.l_len = 0;
@ -373,7 +416,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit)
{
if (fhandle > 0 && (--fhandle < anz_fhandles) ) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles) ) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
if (!(fh->fh_flags & FH_IS_READONLY)) {
@ -389,7 +432,7 @@ int nw_close_datei(int fhandle, int reset_reuse)
{
XDPRINTF((5, 0, "nw_close_datei handle=%d, anz_fhandles",
fhandle, anz_fhandles));
if (fhandle > 0 && (fhandle <= anz_fhandles)) {
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE);
if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) {
@ -434,7 +477,7 @@ int nw_close_datei(int fhandle, int reset_reuse)
uint8 *file_get_unix_name(int fhandle)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
return((uint8*)file_handles[fhandle].fname);
}
return(NULL);
@ -455,7 +498,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite)
int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
open_pipe_command(fh, 0);
@ -519,7 +562,7 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
int nw_seek_datei(int fhandle, int modus)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
@ -541,7 +584,7 @@ int nw_seek_datei(int fhandle, int modus)
int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
open_pipe_command(fh, 1);
@ -584,19 +627,19 @@ int nw_server_copy(int qfhandle, uint32 qoffset,
int zfhandle, uint32 zoffset,
uint32 size)
{
if (qfhandle > 0 && (--qfhandle < anz_fhandles)
&& zfhandle > 0 && (--zfhandle < anz_fhandles) ) {
if (qfhandle > HOFFS && (--qfhandle < anz_fhandles)
&& zfhandle > HOFFS && (--zfhandle < anz_fhandles) ) {
FILE_HANDLE *fhq=&(file_handles[qfhandle]);
FILE_HANDLE *fhz=&(file_handles[zfhandle]);
int retsize = -1;
if (fhq->fd > -1 && fhz->fd > -1) {
char buff[2048];
char buff[4096];
int wsize;
if (fhz->fh_flags & FH_IS_READONLY) return(-0x94);
if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L &&
lseek(fhz->fd, zoffset, SEEK_SET) > -1L) {
retsize = 0;
while (size && !retsize) {
while (size) {
int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff)));
if (xsize > 0){
if ((wsize =write(fhz->fd, buff, xsize)) != xsize) {
@ -614,19 +657,16 @@ int nw_server_copy(int qfhandle, uint32 qoffset,
}
fhq->offd = -1L;
fhz->offd = -1L;
/*
if (!retsize) (retsize=fhz->offd=lseek(fhz->fd, 0L, SEEK_END));
*/
return(retsize);
}
}
return(- 0x88); /* wrong filehandle */
return(-0x88); /* wrong filehandle */
}
int nw_lock_datei(int fhandle, int offset, int size, int do_lock)
{
if (fhandle > 0 && (--fhandle < anz_fhandles)) {
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
struct flock flockd;
@ -642,7 +682,6 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock)
result = fcntl(fh->fd, F_SETLK, &flockd);
XDPRINTF((2, 0, "nw_%s_datei result=%d, fh=%d, offset=%d, size=%d",
(do_lock) ? "lock" : "unlock", result, fhandle, offset, size));
if (!result) return(0);
else return(-0x21); /* LOCK Violation */
} else if (fh->fd == -3) return(0);

View File

@ -1,9 +1,10 @@
/* nwfile.h 11-May-96 */
/* nwfile.h 19-Oct-96 */
#ifndef _NWFILE_H_
#define _NWFILE_H_
#include "nwqueue.h"
typedef struct {
int task; /* for which task */
int fd; /* filehandle from system open/creat */
long offd; /* actual file offset */
#if USE_MMAP
@ -26,11 +27,11 @@ typedef struct {
extern void sig_bus_mmap(int rsig);
extern void init_file_module(void);
extern void init_file_module(int task);
extern int file_creat_open(int volume, uint8 *unixname,
struct stat *stbuff,
int attrib, int access, int creatmode);
int attrib, int access, int creatmode, int task);
extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit);

View File

@ -1,4 +1,4 @@
/* nwconn.c 29-Sep-96 */
/* nwconn.c 19-Oct-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -278,7 +278,7 @@ static int create_queue_file(uint8 *job_file_name,
if (result > -1) {
struct stat stbuff;
result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x6, 1|4|8);
&stbuff, 0x6, 0x6, 1|4|8, 0);
if (result > -1) {
chown(unixname, act_uid, act_gid);
chmod(unixname, 0660);

View File

@ -1,4 +1,4 @@
/* nwroute.c 12-May-96 */
/* nwroute.c 28-Oct-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -438,9 +438,9 @@ static void send_sap_to_addr(int entry, int hops, int ticks,
memset(&ipx_data, 0, sizeof(ipx_data.sip));
strcpy((char*)ipx_data.sip.server_name, nw->name);
memcpy(&ipx_data.sip.server_adr, &nw->addr, sizeof(ipxAddr_t));
XDPRINTF((4, 0, "%s SERVER=%s, typ=0x%x, ticks=%d, hops=%d",
XDPRINTF((4, 0, "%s SERVER=%s, typ=0x%x, ticks=%d, hops=%d, sock=0x%x",
(respond_typ==4) ? "NEAREST" : "GENERAL", nw->name,
nw->typ, ticks, hops));
nw->typ, ticks, hops, (int)GET_BE16(nw->addr.sock)));
U16_TO_BE16(respond_typ, ipx_data.sip.response_type);
U16_TO_BE16(nw->typ, ipx_data.sip.server_type);
U16_TO_BE16(hops, ipx_data.sip.intermediate_networks);
@ -529,16 +529,34 @@ static void send_sap_broadcast(int mode)
}
}
static FILE *open_route_info_fn(int force)
static FILE *open_route_info_fn(int force, FILE *ff, int section)
{
static int tacs=0;
FILE *f=NULL;
if (section>1 && !(print_route_mode&2))
return(ff);
if (print_route_tac > 0) {
if (!tacs || force) {
if (NULL != (f=fopen(pr_route_info_fn,
(print_route_mode) ? "w" : "a"))) {
tacs = print_route_tac-1;
} else print_route_tac=0;
char fnbuf[300];
char *fn;
if (print_route_mode&2) {
sprintf(fnbuf, "%s.%d", pr_route_info_fn, section);
fn = fnbuf;
} else {
fn=pr_route_info_fn;
}
f=fopen(fn, (print_route_mode&0x1) ? "w" : "a");
if (section == 1) {
if (NULL != f)
tacs = print_route_tac-1;
else
print_route_tac=0;
} else {
if (NULL != f)
fclose(ff);
else
f = ff; /* we use old file */
}
} else tacs--;
}
return(f);
@ -546,13 +564,14 @@ static FILE *open_route_info_fn(int force)
void print_routing_info(int force)
{
FILE *f= open_route_info_fn(force);
FILE *f= open_route_info_fn(force, NULL, 1);
if (f) {
int k=-1;
int i;
time_t xtime;
time(&xtime);
fprintf(f, "%s", ctime(&xtime) );
fprintf(f, "<--------- Devices ---------------->\n");
fprintf(f, "<--------- %d Devices ---------------->\n", anz_net_devices);
fprintf(f, "%-15s %-15s %5s Network Status\n", "DevName", "Frame", "Ticks");
while (++k < anz_net_devices) {
uint8 frname[30];
@ -564,7 +583,17 @@ void print_routing_info(int force)
: ( (nd->is_up==1) ? "UP"
: "ADDED") );
}
fprintf(f, "<--------- Routing Table ---------->\n");
if (print_route_mode&2) {
f= open_route_info_fn(1, f, 2);
fprintf(f, "%s", ctime(&xtime) );
}
i=0;
k=-1;
while (++k < anz_routes) {
NW_ROUTES *nr = nw_routes[k];
if (nr->net) i++;
}
fprintf(f, "<--------- %d Routes ---------->\n", i);
fprintf(f, "%8s Hops Ticks %9s Router Node\n", "Network", "RouterNet");
k=-1;
while (++k < anz_routes) {
@ -576,15 +605,25 @@ void print_routing_info(int force)
(int)nr->rnode[3], (int)nr->rnode[4], (int)nr->rnode[5]);
}
}
if (print_route_mode&2) {
f= open_route_info_fn(1, f, 3);
fprintf(f, "%s", ctime(&xtime) );
}
i=0;
k=-1;
fprintf(f, "<--------- Server Table ---------->\n");
while (++k < anz_servers) {
NW_SERVERS *ns = nw_servers[k];
if (ns->typ) i++;
}
fprintf(f, "<--------- %d Servers ---------->\n", i);
fprintf(f, "%-20s %4s %9s Hops Server-Address\n","Name", "Typ", "RouterNet");
k=-1;
while (++k < anz_servers) {
NW_SERVERS *ns = nw_servers[k];
if (ns->typ) {
char sname[50];
strmaxcpy(sname, ns->name, 20);
fprintf(f, "%-20s %4d %08lX %4d %s\n", sname, ns->typ,
fprintf(f, "%-20s %4x %08lX %4d %s\n", sname, ns->typ,
ns->net, ns->hops, xvisable_ipx_adr(&(ns->addr), 1));
}
} /* while */
@ -716,8 +755,7 @@ int test_ins_device_net(uint32 rnet)
if ( foundfree < 0 ) {
if (anz_net_devices < MAX_NET_DEVICES) {
NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]);
nd=*pnd= (NW_NET_DEVICE*)xmalloc(sizeof(NW_NET_DEVICE));
memset(nd, 0, sizeof(NW_NET_DEVICE));
nd=*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE));
nd->ticks = 1;
} else {
XDPRINTF((1, 0, "too many devices > %d, increase MAX_NET_DEVICES in config.h", anz_net_devices));

160
nwserv.c
View File

@ -1,4 +1,4 @@
/* nwserv.c 03-May-96 */
/* nwserv.c 09-Nov-96 */
/* MAIN Prog for NWSERV + NWROUTED */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -120,6 +120,12 @@ static char *prog_name_typ="SERVER";
#define IN_PROG NWSERV
#endif
#if !IN_NWROUTED
static int ipx_out_fd=-1;
/* next should be '1', is for testing only */
#define USE_PERMANENT_OUT_SOCKET 1
static void add_wdata(IPX_DATA *d, char *data, int size)
{
memcpy(d->owndata.d.data+d->owndata.d.size, data, size);
@ -128,18 +134,25 @@ static void add_wdata(IPX_DATA *d, char *data, int size)
static void write_wdata(IPX_DATA *d, int what, int sock)
{
ipxAddr_t toaddr;
d->owndata.d.function=what;
d->owndata.d.size +=sizeof(int);
memset(d->owndata.type, 0xee, 2);
d->owndata.sequence = 0;
d->owndata.connection = 0;
memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t));
U16_TO_BE16(sock, toaddr.sock);
send_ipx_data(-1, 17,
OWN_DATA_IPX_BASE_SIZE + sizeof(int)+d->owndata.d.size, (char*)d,
&toaddr, (sock == SOCK_NCP) ? "NCPSERV" : "NWBIND" );
d->owndata.d.size=0;
int fd = (ipx_out_fd > -1) ? ipx_out_fd : open_ipx_socket(NULL, 0);
if (fd > -1) {
ipxAddr_t toaddr;
d->owndata.d.function=what;
d->owndata.d.size +=sizeof(int);
memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t));
U16_TO_BE16(sock, toaddr.sock);
if (send_own_data(fd, d, &toaddr)) {
errorp(0, "write_wdata", "to %s",
(sock == SOCK_NCP) ? "NCPSERV" : "NWBIND" );
}
d->owndata.d.size=0;
if (ipx_out_fd != fd) {
t_unbind(fd);
t_close(fd);
}
} else {
errorp(0, "write_wdata", "fd not open");
}
}
static void write_to_sons(int what, int connection,
@ -178,12 +191,8 @@ static void write_to_sons(int what, int connection,
write_wdata(&ipxd, what, sock);
}
#if !IN_NWROUTED
# define write_to_ncpserv(what, connection, data, data_size) \
#define write_to_ncpserv(what, connection, data, data_size) \
write_to_sons((what), (connection), (data), (data_size), SOCK_NCP)
#else
# define write_to_ncpserv(what, connection, data, data_size) /* */
#endif
#define write_to_nwbind(what, connection, data, data_size) \
write_to_sons((what), (connection), (data), (data_size), sock_nwbind)
@ -215,39 +224,31 @@ void ins_del_bind_net_addr(uint8 *name, int styp, ipxAddr_t *adr)
write_to_nwbind(0x3333, 0, (char *)buf, len);
}
static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode)
static int loc_open_ipx_socket(int sock_nr, int nr)
{
int ipx_fd=t_open("/dev/ipx", open_mode, NULL);
struct t_bind bind;
if (ipx_fd < 0) {
t_error("t_open !Ok");
return(-1);
}
memset(&my_server_adr, 0, sizeof(ipxAddr_t));
U16_TO_BE16(sock_nr, my_server_adr.sock); /* actual read socket */
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_server_adr;
bind.qlen = 0; /* ever */
if (t_bind(ipx_fd, &bind, &bind) < 0){
char sxx[200];
sprintf(sxx,"NWSERV:t_bind !OK in open_ipx_socket, sock=0x%x", (int) sock_nr);
t_error(sxx);
t_close(ipx_fd);
return(-1);
}
sock_nummern[nr] = GET_BE16(my_server_adr.sock); /* really socket nmbr */
if (nw_debug) print_ipx_addr(&my_server_adr);
int ipx_fd=open_ipx_socket(&my_server_adr, sock_nr);
if (ipx_fd > -1) {
sock_nummern[nr] = GET_BE16(my_server_adr.sock); /* really socket nmbr */
if (nw_debug)
print_ipx_addr(&my_server_adr);
} else
errorp(0, "loc_open_ipx_socket", "nr=%d", sock_nr);
return(ipx_fd);
}
#else
# define USE_PERMANENT_OUT_SOCKET 0
# define write_to_ncpserv(what, connection, data, data_size) /* */
# define write_to_nwbind(what, connection, data, data_size) /* */
#endif
static int start_ncpserv(char *nwname, ipxAddr_t *addr)
{
#if !IN_NWROUTED
int fds_in[2];
int pid;
if (pipe(fds_in) < 0) return(-1);
if (pipe(fds_in) < 0)
return(-1);
switch (pid=fork()) {
case 0 : { /* new Process */
@ -279,30 +280,20 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
close(fds_in[1]);
fd_ncpserv_in = fds_in[0];
pid_ncpserv = pid;
sleep(2);
#endif
U16_TO_BE16(SOCK_NCP, addr->sock);
return(0); /* OK */
}
static int start_nwbind(char *nwname, ipxAddr_t *addr)
static int start_nwbind(char *nwname)
{
#if !IN_NWROUTED
int fds_in[2];
int pid;
struct t_bind bind;
int ipx_fd=t_open("/dev/ipx", O_RDWR, NULL);
int fds_in[2];
int pid;
ipxAddr_t addr;
int ipx_fd=open_ipx_socket(&addr, 0);
if (ipx_fd < 0) {
errorp(1, "start_nwbind", "t_open");
return(-1);
}
U16_TO_BE16(SOCK_AUTO, addr->sock);
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)addr;
bind.qlen = 0; /* allways */
if (t_bind(ipx_fd, &bind, &bind) < 0){
errorp(1, "start_nwbind", "t_bind");
t_close(ipx_fd);
errorp(1, "start_nwbind", NULL);
return(-1);
}
if (pipe(fds_in) < 0){
@ -310,8 +301,7 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr)
t_close(ipx_fd);
return(-1);
}
sock_nwbind = (int) GET_BE16(addr->sock);
sock_nwbind = (int) GET_BE16(addr.sock);
switch (pid=fork()) {
case 0 : { /* new Process */
char *progname="nwbind";
@ -329,8 +319,8 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr)
close(ipx_fd);
while (j++ < 100) close(j); /* close all > FD_NWSERV */
U16_TO_BE16(SOCK_NCP, addr->sock);
ipx_addr_to_adr(addrstr, addr);
U16_TO_BE16(SOCK_NCP, addr.sock);
ipx_addr_to_adr(addrstr, &addr);
sprintf(nwbindsock, "%04x", sock_nwbind);
execl(get_exec_path(pathname, progname), progname,
nwname, addrstr, nwbindsock, NULL);
@ -348,6 +338,7 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr)
close(ipx_fd);
fd_nwbind_in = fds_in[0];
pid_nwbind = pid;
sleep(2);
#endif
return(0); /* OK */
}
@ -535,7 +526,7 @@ static void handle_sap(int fd,
int server_type = GET_BE16(ipxdata->sqp.server_type);
if (query_type == 3) {
XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d von %s",
XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d from %s",
server_type, visable_ipx_adr(from_addr)));
/* Get Nearest File Server */
if (!nearest_request_flag)
@ -570,8 +561,9 @@ static void handle_sap(int fd,
/* if (hops < 16) hops++; */
XDPRINTF((2,0, "TYP=%2d,hops=%2d, Addr=%s, Name=%s", type, hops,
visable_ipx_adr(ad), name));
#if !HANDLE_ALL_SAP_TYPS
if (type == 4) { /* from Fileserver */
#endif
if (16 == hops) {
/* shutdown */
XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name));
@ -580,7 +572,9 @@ static void handle_sap(int fd,
get_server_data((char*)name, ad, from_addr);
insert_delete_server(name, type, ad, from_addr, hops, 0, 0);
}
#if !HANDLE_ALL_SAP_TYPS
}
#endif
p+=sizeof(SAPS);
} /* while */
} else {
@ -836,8 +830,7 @@ static void get_ini(int full)
break;
#if INTERNAL_RIP_SAP
case 3 :
if (full) {
case 3 : if (full) {
upstr(inhalt);
if (!strcmp(inhalt, "AUTO")) internal_net = 0;
else {
@ -856,12 +849,14 @@ static void get_ini(int full)
if (NULL != hent && hent->h_length == 4) {
internal_net = GET_BE32(*(hent->h_addr_list));
} else {
XDPRINTF((0, 0, "Cannot gethostbyname from '%s'",
locname));
errorp(10, "Get_ini", "Cannot gethostbyname from '%s'",
locname);
if (hent) {
XDPRINTF((0, 0, "hent->h_length=%d", hent->h_length));
}
}
if (0==internal_net)
errorp(11, "Get_ini", "Cannot get AUTO internal net with help of gethostbyname");
}
}
break;
@ -881,7 +876,7 @@ static void get_ini(int full)
if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1)
sscanf(inhalt, "%lx", &nd->net);
if (nd->net == internal_net) {
if (nd->net && (nd->net == internal_net)) {
errorp(11, "Get_ini", "device net 0x%lx = internal net", nd->net);
exit(1);
}
@ -939,7 +934,7 @@ static void get_ini(int full)
case 301 : new_str(pr_route_info_fn, (uint8*)inhalt);
break;
case 302 : print_route_mode=atoi(inhalt);
case 302 : print_route_mode=hextoi(inhalt);
break;
case 310 : wdogs_till_tics=atoi(inhalt);
@ -1028,7 +1023,12 @@ static void send_down_broadcast(void)
static void close_all(void)
{
int j = NEEDED_SOCKETS;
#if USE_PERMANENT_OUT_SOCKET
if (ipx_out_fd > -1) {
t_unbind(ipx_out_fd);
t_close(ipx_out_fd);
}
#endif
while (j--) {
t_unbind(sockfd[j]);
t_close(sockfd[j]);
@ -1189,7 +1189,7 @@ int main(int argc, char **argv)
polls[j].events = POLLIN|POLLPRI;
polls[j].revents = 0;
if (j < NEEDED_SOCKETS) {
int fd = open_ipx_socket(ipx_sock_nummern[j], j, O_RDWR);
int fd = loc_open_ipx_socket(ipx_sock_nummern[j], j);
if (fd < 0) {
while (j--) {
t_unbind(sockfd[j]);
@ -1205,11 +1205,20 @@ int main(int argc, char **argv)
}
}
#if USE_PERMANENT_OUT_SOCKET
ipx_out_fd=open_ipx_socket(NULL, 0);
#endif
#if !IN_NWROUTED
XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s",
(ipx_out_fd > -1) ? "enabled" : "disabled"));
XDPRINTF((1, 0, "IPX_MAX_DATA=%d, RW_BUFFERSIZE =%d",
IPX_MAX_DATA, RW_BUFFERSIZE));
signal(SIGCHLD, sig_chld);
#endif
if ( !start_nwbind( my_nwname, &my_server_adr)
if ( !start_nwbind(my_nwname)
&& !start_ncpserv(my_nwname, &my_server_adr) ) {
/* now do polling */
time_t broadtime;
@ -1217,18 +1226,17 @@ int main(int argc, char **argv)
set_sigs();
polls[NEEDED_SOCKETS].fd = fd_nwbind_in;
U16_TO_BE16(SOCK_NCP, my_server_adr.sock);
#if !IN_NWROUTED
{
ipxAddr_t server_adr_sap;
polls[NEEDED_SOCKETS+1].fd = fd_ncpserv_in;
U16_TO_BE16(SOCK_NCP, my_server_adr.sock);
memcpy(&server_adr_sap, &my_server_adr, sizeof(ipxAddr_t));
U16_TO_BE16(SOCK_SAP, server_adr_sap.sock);
insert_delete_server((uint8*)my_nwname, 0x4,
&my_server_adr, &server_adr_sap, 0, 0, 0);
}
#endif
while (!server_is_down) {
int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs);
int call_wdog=0;

View File

@ -1,4 +1,4 @@
/* nwvolume.c 08-Aug-96 */
/* nwvolume.c 07-Nov-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -33,6 +33,18 @@
NW_VOL nw_volumes[MAX_NW_VOLS];
int used_nw_volumes=0;
static void volume_to_namespace_map(int volume, NW_VOL *vol)
{
struct stat statb;
DEV_NAMESPACE_MAP dnm;
if (stat(vol->unixname, &statb)) {
XDPRINTF((1, 0, "cannot stat vol=%d, `%s`", volume, vol->unixname));
}
dnm.dev = statb.st_dev;
dnm.namespace = 0; /* NAMESPACE DOS */
(void) nw_vol_inode_to_handle(volume, statb.st_ino, &dnm);
}
void nw_init_volumes(FILE *f)
/* f = inifile Pointer, must be opened !! */
{
@ -123,7 +135,8 @@ void nw_init_volumes(FILE *f)
vol->max_maps_count = MAX_DEV_NAMESPACE_MAPS;
vol->high_inode = 0xfffffff;
}
if (vol->unixnamlen)
volume_to_namespace_map(used_nw_volumes-1, vol);
}
}
} /* while */
@ -141,10 +154,15 @@ void nw_setup_home_vol(int len, uint8 *fn)
unixname[len] = '\0';
}
}
while (k--) {
while (k--) { /* now set all HOME volumes */
if (nw_volumes[k].options & VOL_OPTION_IS_HOME) {
int i = -1;
while (++i < nw_volumes[k].maps_count)
xfree(nw_volumes[k].dev_namespace_maps[i]);
nw_volumes[k].maps_count = 0;
nw_volumes[k].unixnamlen = len;
new_str(nw_volumes[k].unixname, unixname);
volume_to_namespace_map(k, &(nw_volumes[k]));
}
}
}