mars_nwe-0.97.pl00

This commit is contained in:
Mario Fetka 2011-11-13 00:38:56 +01:00
parent fc81c57450
commit 3c4372643c
29 changed files with 1286 additions and 529 deletions

84
README
View File

@ -1,71 +1,25 @@
(C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany This is Mars_nwe, a free NetWare(tm) emulator for Linux and UnixWare,
written by Martin Stover, Marburg, Germany.
to compile and install, please read INSTALL ! There is not yet too much documentation available, look into the doc/
subdirectory. As Martin's native tongue is german, the documentation,
as well as a lot of the code comments are a mixture of english and
german. This will certainly converge to english in the future.
This is a little try to emulate some functions from INSTALLATION
a NOVELL-SERVER under UNIX (LINUX). look in doc/INSTALL or doc/INSTALL.ger
The first version I have written 1993 on a USL1.1
with TLI-Code.
1994 I have ported it to LINUX. This was easy, because
I only have to write a small TLI->SOCKET emu.
Unfortunately I had no full description of the NCP-calls,
so many of the calls based on trying. :-(
WARNING: this code has still many BUG's !!
BINDERY: this are the *.pag and *.dir files.
These files are generated by the first starting
of mars_nwe and are filled with the minimal
needed Objects and Properties.
The User SUPERVISOR must be described in the
nw.ini file, entry 12
NETWORK: If there is a real Novell-Server on the
same net-line, then the NETWORK Number of
the network device in nw.ini should match
the NETWORK Number of the Novell-Server.
LINUX
KERNEL: the only linux-kernel depending files
are emutli.[hc].
short description of the processes.
1) nwserv : the main program.Initiates all and starts 'ncpserv'.
sends broadcasts, wdogs, sap and rip packets.
If nwserv is started with a parameter, then the simple
test client 'nwclient', only for debugging, is started.
2) ncpserv: opens NCP-Socket and handles NCP-Requests.
When there comes NCP-Request 0x1111 (Get Connection Nr)
then there will be started a new process 'nwconn'.
Every client-ncp-request reaches nwconn over
ncpserv.
3) nwconn: will be started for every connection. Is connected
to ncpserv with a pipe.
Problems and TODO:
Many:-(
Here is a short list.
o - password changings from clients
o - make routing better.
o - making printing better.
o - clean the code !!!
o - make bindery code more complete.
o - and much more ...
Have luck with trying. :)
Martin HELP
(mstover@freeway.de)
BTW: The kick to make mars_nwe public was the To get help you can mail to and/or subscribe to LinWare mailing list:
publication of linware ( lwared ), the Novell-Server-Emulator
from Ales Dryak (A.Dryak@sh.cvut.cz).
I hope both products can make profit from each other.
-----> SuperNOS ala Linux ;-)
Novell don't want to make it anymore. :-(
Topics for the list:
- discussing LinWare server, its features, installation problems and bugs
- using IPX protocol under Linux
- IPX routing and router daemons under Linux
- mars_nwe
You can subscribe to the list by sending command "add linware" in mail
message body to address: "listserv@sh.cvut.cz".
Your list postings should be sent to address: "linware@sh.cvut.cz".

View File

@ -1,4 +1,4 @@
/* connect.c 23-Jan-96 */ /* connect.c 10-Mar-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -30,6 +30,9 @@ extern int errno;
static int test_handle=-1; static int test_handle=-1;
#endif #endif
#define DONT_KNOW_IF_OK 1
static int default_uid=-1; static int default_uid=-1;
static int default_gid=-1; static int default_gid=-1;
@ -158,8 +161,8 @@ void set_default_guid(void)
{ {
seteuid(0); seteuid(0);
if (setegid(default_gid) < 0 || seteuid(default_uid) < 0) { if (setegid(default_gid) < 0 || seteuid(default_uid) < 0) {
fprintf(stderr, "Cannot set default gid=%d and uid=%d\nABORTET!!\n" , errorp(1, "set_default_guid, !! Abort !!",
default_gid, default_uid); "Cannot set default gid=%d and uid=%d" , default_gid, default_uid);
exit(1); exit(1);
} }
} }
@ -680,6 +683,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
return(completition); return(completition);
} }
static int lastdirhandle=0;
int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
uint8 *data, int len, int only_dir) uint8 *data, int len, int only_dir)
/* /*
@ -687,7 +691,15 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
* else a negativ errcode will be returned * else a negativ errcode will be returned
*/ */
{ {
int completition = build_path(nwpath, data, len, only_dir); int completition;
#if DONT_KNOW_IF_OK
if (!dirhandle && len > 1 && *data== ':' && *(data+1) == '/') {
--len;
data++;
dirhandle = lastdirhandle;
} else if (dirhandle) lastdirhandle = dirhandle;
#endif
completition = build_path(nwpath, data, len, only_dir);
if (!completition) completition = build_verz_name(nwpath, dirhandle); if (!completition) completition = build_verz_name(nwpath, dirhandle);
return(completition); return(completition);
} }
@ -810,6 +822,13 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus)
struct stat stbuff; struct stat stbuff;
int completition=-0x9c; int completition=-0x9c;
NW_PATH nwpath; NW_PATH nwpath;
#if DONT_KNOW_IF_OK
if (!dir_handle && len > 1 && *data== ':' && *(data+1) == '/') {
--len;
data++;
dir_handle = lastdirhandle;
} else if (dir_handle) lastdirhandle = dir_handle;
#endif
build_path(&nwpath, data, len, 0); build_path(&nwpath, data, len, 0);
if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */ if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */
completition = build_verz_name(&nwpath, dir_handle); completition = build_verz_name(&nwpath, dir_handle);
@ -924,6 +943,13 @@ static int change_dir_entry( NW_DIR *dir, int volume,
} }
} }
void nw_exit_connect(void)
{
if (connect_is_init) {
init_file_module();
}
}
int nw_init_connect(void) int nw_init_connect(void)
/* Cann be called when ever you want */ /* Cann be called when ever you want */
{ {
@ -971,12 +997,12 @@ int nw_init_connect(void)
fclose(f); fclose(f);
if (used_nw_volumes < 1) { if (used_nw_volumes < 1) {
errorp(0, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL);
return(-1); return(-1);
} }
if (stat(build_unix_name(&nwlogin, 0), &stbuff)) { if (stat(build_unix_name(&nwlogin, 0), &stbuff)) {
errorp(0, "Stat error LOGIN Directory, Abort !!", errorp(1, "Stat error LOGIN Directory, Abort !!",
"UnixPath=`%s`", build_unix_name(&nwlogin, 0)); "UnixPath=`%s`", build_unix_name(&nwlogin, 0));
return(-1); return(-1);
} }
@ -1052,7 +1078,7 @@ int nw_search(uint8 *info,
{ {
NW_PATH nwpath; NW_PATH nwpath;
int completition = conn_get_kpl_path(&nwpath, dirhandle, data, len, 0); int completition= conn_get_kpl_path(&nwpath, dirhandle, data, len, 0);
XDPRINTF((5,0,"nw_search path:%s:, fn:%s:, completition:0x%x", XDPRINTF((5,0,"nw_search path:%s:, fn:%s:, completition:0x%x",
nwpath.path, nwpath.fn, completition)); nwpath.path, nwpath.fn, completition));
if (completition > -1) { if (completition > -1) {

View File

@ -1,4 +1,4 @@
/* connect.h 28-Jan-96 */ /* connect.h 10-Mar-96 */
#ifndef _CONNECT_H_ #ifndef _CONNECT_H_
#define _CONNECT_H_ #define _CONNECT_H_
typedef struct { typedef struct {
@ -53,6 +53,8 @@ typedef struct {
extern int nw_init_connect(void); extern int nw_init_connect(void);
extern void nw_exit_connect(void);
extern int nw_free_handles(int task); extern int nw_free_handles(int task);
extern int nw_creat_open_file(int dir_handle, uint8 *data, int len, extern int nw_creat_open_file(int dir_handle, uint8 *data, int len,

View File

@ -83,7 +83,15 @@ Erste 'oeffentliche' Version
- Passwort Strategy erweitert. Nun ist es auch moeglich ueber - Passwort Strategy erweitert. Nun ist es auch moeglich ueber
entry '7' in der ini Datei System-Passwoerter zu verwenden. entry '7' in der ini Datei System-Passwoerter zu verwenden.
Es werden dann unencryted Passwoerter verwendet. Es werden dann unencryted Passwoerter verwendet.
- Neuer Eintrag '15' in ini Datei eingebaut zwecks automatischen
Einlesen von User in die Bindery.
- Moeglichkeit zum Testen/Anlegen der Standarddirs beim Starten
eingebaut.
- Bindery Code veraendert, Dateien bleiben nun geoeffnet.
- Kommunikation ncpserv <-> nwconn von Pipe auf Socket abgeaendert.
- Moeglichkeit zu Leistungssteigerung mittels modifizierten ipx-kernel
eingebaut.
- entry '6' erweitert. Nun ist 3.12 Angabe moeglich.
- Moeglichkeit der stationsabhaengigen Steuerung von
Nearest Server Response eingebaut.
^^^^^^^^^^ VERSION 0.97 ^^^^^^^^

View File

@ -1,4 +1,21 @@
------13-Feb-96--------- # in this files are important notes for user of mars_nwe.
------10-Mar-96--- 0.97.pl0 ----------
New Conf-file entry '211' for broadcast periods.
Entries 400, 401 for special handling of the nearest server request.
-
Conf-file entry '6' enlarged.
-
New Entries '15' + '16' in conf-file.
With entry '15' you can allow mars_nwe insert all not yet known
users from /etc/passwd to mars_nwe bindery. But be carefully,
all new inserted users will get the same password from entry '15'.
-
If entry '16' is enabled ( '1' ) then mars_nwe will make some
checks for bindery and 'SYS:' directory.
For every user a MAIL/XXXXX dir will also be created.
-
Much more better bindery performance. :)
------13-Feb-96--- 0.96.pl9 ----------
New alternative password strategy in mars_nwe: New alternative password strategy in mars_nwe:
There is an new entry '7' in ini/conf file. There is an new entry '7' in ini/conf file.

71
doc/README Normal file
View File

@ -0,0 +1,71 @@
(C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
to compile and install, please read INSTALL !
This is a little try to emulate some functions from
a NOVELL-SERVER under UNIX (LINUX).
The first version I have written 1993 on a USL1.1
with TLI-Code.
1994 I have ported it to LINUX. This was easy, because
I only have to write a small TLI->SOCKET emu.
Unfortunately I had no full description of the NCP-calls,
so many of the calls based on trying. :-(
WARNING: this code has still many BUG's !!
BINDERY: this are the *.pag and *.dir files.
These files are generated by the first starting
of mars_nwe and are filled with the minimal
needed Objects and Properties.
The User SUPERVISOR must be described in the
nw.ini file, entry 12
NETWORK: If there is a real Novell-Server on the
same net-line, then the NETWORK Number of
the network device in nw.ini should match
the NETWORK Number of the Novell-Server.
LINUX
KERNEL: the only linux-kernel depending files
are emutli.[hc].
short description of the processes.
1) nwserv : the main program.Initiates all and starts 'ncpserv'.
sends broadcasts, wdogs, sap and rip packets.
If nwserv is started with a parameter, then the simple
test client 'nwclient', only for debugging, is started.
2) ncpserv: opens NCP-Socket and handles NCP-Requests.
When there comes NCP-Request 0x1111 (Get Connection Nr)
then there will be started a new process 'nwconn'.
Every client-ncp-request reaches nwconn over
ncpserv.
3) nwconn: will be started for every connection. Is connected
to ncpserv with a pipe.
Problems and TODO:
Many:-(
Here is a short list.
o - password changings from clients
o - make routing better.
o - making printing better.
o - clean the code !!!
o - make bindery code more complete.
o - and much more ...
Have luck with trying. :)
Martin
(mstover@freeway.de)
BTW: The kick to make mars_nwe public was the
publication of linware ( lwared ), the Novell-Server-Emulator
from Ales Dryak (A.Dryak@sh.cvut.cz).
I hope both products can make profit from each other.
-----> SuperNOS ala Linux ;-)
Novell don't want to make it anymore. :-(

View File

@ -1,7 +1,7 @@
Begin3 Begin3
Title: mars_nwe Title: mars_nwe
Version: 0.96pl9 Version: 0.97
Entered-date: 13-Feb-96 Entered-date: 10-Mar-96
Description: full novell-server-emulator (src),beta Description: full novell-server-emulator (src),beta
supports file-services, bindery-services, supports file-services, bindery-services,
printing-services, routing-services printing-services, routing-services
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@freeway.de (Martin Stover) Author: mstover@freeway.de (Martin Stover)
Maintained-by: mstover@freeway.de (Martin Stover) Maintained-by: mstover@freeway.de (Martin Stover)
Primary-site: linux01.gwdg.de /pub/ncpfs Primary-site: linux01.gwdg.de /pub/ncpfs
110kB mars_nwe-0.96.pl9.tgz 110kB mars_nwe-0.97.tgz
Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware
Platforms: Linux (1.2.xx, 1.3.32, > 1.3.55 tested, others should work) Platforms: Linux (1.2.xx, 1.3.32, > 1.3.55 tested, others should work)
Copying-policy: GNU Copying-policy: GNU

View File

@ -36,6 +36,11 @@ typedef struct {
uint8 sock[IPX_SOCK_SIZE]; uint8 sock[IPX_SOCK_SIZE];
} ipxAddr_t; } ipxAddr_t;
#define IPXCMPSOCK(a, b) ( \
((char *)(a))[0] == ((char*)(b))[0] && \
((char *)(a))[1] == ((char*)(b))[1] \
)
#define IPXCMPNODE(a, b) ( \ #define IPXCMPNODE(a, b) ( \
((char *)(a))[0] == ((char*)(b))[0] && \ ((char *)(a))[0] == ((char*)(b))[0] && \
((char *)(a))[1] == ((char*)(b))[1] && \ ((char *)(a))[1] == ((char*)(b))[1] && \

View File

@ -1,3 +1,4 @@
!! this dosemupatch is _not_ needed for kernel >= 1.3.71 :) !!
If dosemu don't work together with mars_nwe you should apply If dosemu don't work together with mars_nwe you should apply
the dirty dosemu-patch to the dosemu program. the dirty dosemu-patch to the dosemu program.
In 1.3.6? the changing of an existing route over the internal net In 1.3.6? the changing of an existing route over the internal net

View File

@ -1,4 +1,4 @@
!! this kernelpatch is not needed for kernel >= 1.3.60 :) !! !! this kernelpatch is _not_ needed for kernel >= 1.3.60 :) !!
this kernelpatch for clean kernels 1.3.56,57,58, pur 59 makes 3 things. this kernelpatch for clean kernels 1.3.56,57,58, pur 59 makes 3 things.

View File

@ -1,9 +1,17 @@
/* config.h: 08-Feb-96 */ /* config.h: 01-Mar-96 */
/* some of this config is needed by make, others by cc */ /* some of this config is needed by make, others by cc */
#define DO_DEBUG 1 /* Debugging einschalten */ #define DO_DEBUG 1 /* Compile in debug code */
#define FILENAME_NW_INI "/etc/nwserv.conf" /* full name of ini (conf) file */ #define DO_TESTING 0
#define PATHNAME_PROGS "/sbin" /* path location of progs */
#define PATHNAME_BINDERY "/etc" /* path location of bindery */ #if DO_TESTING
# define FILENAME_NW_INI "./nw.ini" /* full name of ini (conf) file */
# define PATHNAME_PROGS "." /* path location of progs */
# define PATHNAME_BINDERY "." /* path location of bindery */
#else
# define FILENAME_NW_INI "/etc/nwserv.conf" /* full name of ini (conf) file */
# define PATHNAME_PROGS "/sbin" /* path location of progs */
# define PATHNAME_BINDERY "/etc" /* path location of bindery */
#endif
#define NETWORK_SERIAL_NMBR 0x44444444L /* Serial Number 4 Byte */ #define NETWORK_SERIAL_NMBR 0x44444444L /* Serial Number 4 Byte */
#define NETWORK_APPL_NMBR 0x2222 /* Applikation Number 2 Byte */ #define NETWORK_APPL_NMBR 0x2222 /* Applikation Number 2 Byte */
@ -13,21 +21,21 @@
#define MAX_NW_VOLS 10 /* max. Volumes */ #define MAX_NW_VOLS 10 /* max. Volumes */
#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ #define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */
#define WITH_NAME_SPACE_CALLS 0 /* Namespace Calls are only badly */ #define WITH_NAME_SPACE_CALLS 0 /* Namespace Calls are only minimal */
/* supported till now. */ /* supported till now. */
/* to enable testing of them this */ /* to enable testing of them this */
/* entry must be changed to '1' and */ /* entry must be changed to '1' and */
/* entry '6' in ini file must be set */ /* entry '6' in ini file must be set */
/* to '1', too. */ /* to > '0', too. */
#define MAX_NW_SERVERS 40 /* max. count of servers */ #define MAX_NW_SERVERS 40 /* max. count of servers */
/* <--------------- next is for linux only -------------------> */ /* <--------------- next is for linux only -------------------> */
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap process */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */
#define MAX_NET_DEVICES 5 /* max. Netdevices, frames */ #define MAX_NET_DEVICES 5 /* max. Netdevices, frames */
#define MAX_NW_ROUTES 50 /* max. networks (internal + external) */ #define MAX_NW_ROUTES 50 /* max. networks (internal + external) */
/* this is for very special use of mars_nwe to only act as a router */ /* this is for very special use of mars_nwe to only act as a router */
#define FILE_SERVER_INACTIV 0 /* 1 = ncpserv will not be startet */ #define FILE_SERVER_INACTIV 0 /* 1 = don't start ncpserv */

View File

@ -1,5 +1,5 @@
# (C)opyright 1993, 1995, Martin Stover, Softwareentwicklung, Marburg # (C)opyright 1993, 1996, Martin Stover, Softwareentwicklung, Marburg
# last change: 13-Feb-96 # last change: 08-Mar-96
# MAR.S NW-Server Emulator # MAR.S NW-Server Emulator
# Einfache Konfiguration, alles ab # ist Kommentar. # Einfache Konfiguration, alles ab # ist Kommentar.
# Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt. # Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt.
@ -52,16 +52,16 @@
# simple namespace services are implemented for testing # simple namespace services are implemented for testing
# since V 0.96pl8. To test them, this entry must be set to '1'. # since V 0.96pl8. To test them, this entry must be set to '1'.
# and config.h must be altered to allow namespace calls. # and config.h must be altered to allow namespace calls.
6 0 # tells server version: 2.15=0, 3.11=1 6 0 # tells server version: 0=2.15, 1=3.11, 2=3.12
# Password handling # Password handling
7 0 # 0 = use only encrypted passwords stuff (default) 7 0 # 0 = use only encrypted passwords stuff (default)
# 1 = allow the unencrypted change password routine. # 1 = allow the unencrypted change password routine.
# 8 = allow all unencrypted stuff. # 8 = allow all unencrypted stuff.
# 9 = use all unencryted calls + get crypt key will allways fail # 9 = use all unencryted calls + get crypt key will allways fail
# so the login program will use the old unencryted calls. # so the login program will use the old unencryted calls.
###################################### ######################################
# GID and UID for _minimal_ rights # GID and UID for _minimal_ rights
# will be used for not logins # will be used for not logins or not assigned mars_nwe users.
10 200 # GID 10 200 # GID
11 201 # UID 11 201 # UID
############################# #############################
@ -77,6 +77,17 @@
## NW-Name UNIX-Name [PASSWORD] ## NW-Name UNIX-Name [PASSWORD]
#13 MAR mar # others #13 MAR mar # others
#13 ALF mar # others #13 ALF mar # others
#####
# Read UnixUsers automaticly from passwd into bindery
# switch password
15 0 secure11
# ^^^ 0=off (default), 1=on, 99=overwrite existing users.
# !!! IMPORTANT !!!
# If you enable this feature you should chose a secure
# password for the users, because all not existent
# mars_nwe users will be inserted into bindery with this password.
###############
16 1 # enable some bindery and sys dir tests/creats after starting.
############################# #############################
# entry 21 for simple print queues # entry 21 for simple print queues
# the queue Directory must exist before printing !!! # the queue Directory must exist before printing !!!
@ -85,7 +96,7 @@
#21 Q2 SYS:/PRINT/Q2 lpr -C printer2 #21 Q2 SYS:/PRINT/Q2 lpr -C printer2
############################# #############################
# >= 100 debug flags, # >= 100 debug flags,
# 0=nodebug, 1=mindebug(errors), 99=maxdebug # 0=nodebug, 1=mindebug(errors+notes), 99=maxdebug
100 0 # debug IPX KERNEL (0 | 1) 100 0 # debug IPX KERNEL (0 | 1)
101 1 # debug NWSERV 101 1 # debug NWSERV
102 0 # debug NCPSERV 102 0 # debug NCPSERV
@ -95,17 +106,24 @@
200 1 # 0 = no logfile and dont daemonize nwserv 200 1 # 0 = no logfile and dont daemonize nwserv
# # 1 = daemonize nwserv and use logfile # # 1 = daemonize nwserv and use logfile
201 /tmp/nw.log # logfilename 201 /tmp/nw.log # logfilename
202 1 # creat new logfile=1, append logfile=0 202 1 # 1=creat new logfile, 0=append to logfile
############################# #############################
210 10 # 1 .. 600 (default 10) seconds after server really goes down 210 10 # 1 .. 600 (default 10) seconds after server really goes down
# # after a down command # # after a down command
211 60 # 10 .. 600 (default 60) broadcasts every x seconds
############################# #############################
300 0 # > 0 print routing info to file every x broadcasts. ( minutes ) 300 0 # > 0 print routing info to file every x broadcasts. ( normally minutes )
301 /tmp/nw.routes # filename. 301 /tmp/nw.routes # filename.
302 1 # creat new filename=1, append to file=0 302 1 # creat new filename=1, append to file=0
############################# #############################
310 7 # send wdog's only to device net < x tics. 310 7 # send wdog's only to device net < x tics.
# 0 = allways send wdogs. < 0 = never send wdogs # 0 = allways send wdogs. < 0 = never send wdogs
##############################
# station file for special handling of stations.
400 /etc/nwserv.stations # for syntax see file in the examples directory.
# for special handling of the 'get nearest server request'.
401 0 # 0 = ignore entry 400, get nearest response ever enabled.
# 1 = 400 are excludes, get nearest response normally enabled.
# 2 = 400 are includes, get nearest response normally disabled.
###

14
examples/nwserv.stations Normal file
View File

@ -0,0 +1,14 @@
# you can put station id's into this file for special handlings
# syntax: EntryNr net:node:socket (in hex notation or wildcards '?' and '*' )
# it will be only a very simple matchcoded string compare, therefore you
# must use the correct syntax.
#
#1 0.0.0.22:0.80.48.55.3f.33:50.3 # one special client socket
#1 0.0.0.22:0.80.48.55.3f.33:40.* # one special client socket >= 0x4000
#1 0.0.0.22:0.80.48.55.3f.32:* # one special client
#1 0.0.0.22:0.80.48.55.3f.2?:* # some clients 20 .. 29
#1 0.0.0.21:* # one special net
# entry 1: is for get nearest server request handling.
# look also into the examples/nw.ini file.

View File

@ -1,5 +1,5 @@
#if 0 #if 0
#makefile.unx 10-Feb-96 #makefile.unx 08-Mar-96
#endif #endif
VPATH=$(V_VPATH) VPATH=$(V_VPATH)
@ -8,9 +8,9 @@ O=.o
C=.c C=.c
V_H=0 V_H=0
V_L=96 V_L=97
P_L=9 P_L=0
#define D_P_L 1 #define D_P_L 0
DISTRIB=mars_nwe DISTRIB=mars_nwe
#if D_P_L #if D_P_L
DISTRIBF=$(DISTRIB)-$(V_H).$(V_L).pl$(P_L) DISTRIBF=$(DISTRIB)-$(V_H).$(V_L).pl$(P_L)
@ -128,10 +128,11 @@ $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h
$(OBJS): net.h config.h $(OBJS): net.h config.h
$(C)$(O): $(C)$(O):
$(CC) -c $(CFLAGS) $(HOSTCFLAGS) \ $(CC) -c $(CFLAGS) $(HOSTCFLAGS)\
-D_VERS_H_=$(V_H) -D_VERS_L_=$(V_L) -D_VERS_P_=$(P_L) $< -D_VERS_H_=$(V_H) -D_VERS_L_=$(V_L) -D_VERS_P_=$(P_L) $<
n_all: $(PROGS) n_all: $(PROGS)
@echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes
n_install_ini: n_install_ini:
cd $(VPATH) && $(INSTALL) -m 664 nw.ini $(M_FILENAME_NW_INI) && cd $(OBJDIR) cd $(VPATH) && $(INSTALL) -m 664 nw.ini $(M_FILENAME_NW_INI) && cd $(OBJDIR)
@ -160,7 +161,10 @@ echo ""; \
fi; cd $(OBJDIR) ) fi; cd $(OBJDIR) )
n_clean1: n_clean1:
cd $(VPATH) && (rm -f ~* examples/~* examples/.e.pck; cd $(OBJDIR)) cd $(VPATH) && (\
find . \( -name .e.pck -o -name '~*' -o -name '*~' -o -name core \) \
-exec rm {} \; \
; cd $(OBJDIR))
n_clean: n_clean1 n_clean: n_clean1
rm -f *.o rm -f *.o
@ -173,23 +177,21 @@ n_make_dir: n_clean1
cd $(VPATH) && (rm -rf $(OBJDIR)/$(VPATH)/$(DISTRIB) \ cd $(VPATH) && (rm -rf $(OBJDIR)/$(VPATH)/$(DISTRIB) \
; mkdir $(DISTRIB) \ ; mkdir $(DISTRIB) \
; mkdir $(DISTRIB)/examples \ ; mkdir $(DISTRIB)/examples \
; mkdir $(DISTRIB)/doc \
; ln -f \ ; ln -f \
$(STERN).[ch] \ $(STERN).[ch] \
makefile.unx \ makefile.unx \
Makefile \ Makefile \
COPYING \ COPYING \
NEWS \
CHANGES \
README \ README \
README.ger \
INSTALL \
INSTALL.ger \
$(DISTRIB).lsm \
$(DISTRIB)/. \ $(DISTRIB)/. \
; rm -f $(DISTRIB)/config.h \ ; rm -f $(DISTRIB)/config.h \
; ln -f \ ; ln -f \
examples/$(STERN) \ examples/$(STERN) \
$(DISTRIB)/examples/. \ $(DISTRIB)/examples/. \
; ln -f \
doc/$(STERN) \
$(DISTRIB)/doc/. \
; cd $(OBJDIR) ) ; cd $(OBJDIR) )
n_diff: n_make_dir n_diff: n_make_dir
@ -202,28 +204,22 @@ n_distrib: n_diff
-mkdir /tmp/x -mkdir /tmp/x
cd $(VPATH) && (tar cvzf $(DISTRIBF).tgz $(DISTRIB) \ cd $(VPATH) && (tar cvzf $(DISTRIBF).tgz $(DISTRIB) \
; uue $(DISTRIBF).tgz; mv -f $(DISTRIB)-$(V_H).uue $(DISTRIBF).uue \ ; uue $(DISTRIBF).tgz; mv -f $(DISTRIB)-$(V_H).uue $(DISTRIBF).uue \
; cp -a $(DISTRIB)/$(DISTRIB).lsm /tmp/yy \ ; cp -a $(DISTRIB)/doc/$(DISTRIB).lsm /tmp/yy \
; echo "" >> /tmp/yy \ ; echo "" >> /tmp/yy \
; echo "" >> /tmp/yy \ ; echo "" >> /tmp/yy \
; cat $(DISTRIBF).uue >> /tmp/yy \ ; cat $(DISTRIBF).uue >> /tmp/yy \
; chmod 664 /tmp/yy \ ; chmod 664 /tmp/yy \
; rm $(DISTRIBF).uue \ ; rm $(DISTRIBF).uue \
; mv $(DISTRIBF).tgz /tmp/x/. \ ; mv $(DISTRIBF).tgz /tmp/x/. \
; cp -a $(DISTRIB)/$(DISTRIB).lsm /tmp/x/. \ ; cp -a $(DISTRIB)/doc/$(DISTRIB).lsm /tmp/x/. \
; cd $(OBJDIR) ) ; cd $(OBJDIR) )
n_distrib_bin: n_distrib_bin:
cd $(VPATH) && (tar cvzf /tmp/$(DISTRIB).bin.tgz \ cd $(VPATH) && (tar cvzf /tmp/$(DISTRIB).bin.tgz \
$(PROGS) \ $(PROGS) \
COPYING \ COPYING \
INSTALL \
INSTALL.ger \
NEWS \
CHANGES \
README \ README \
README.ger \
$(DISTRIB).lsm \
examples \ examples \
doc \
; cd $(OBJDIR)) ; cd $(OBJDIR))

550
ncpserv.c
View File

@ -1,5 +1,5 @@
/* ncpserv.c */ /* ncpserv.c */
#define REVISION_DATE "13-Feb-96" #define REVISION_DATE "10-Mar-96"
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -19,7 +19,11 @@
#include "net.h" #include "net.h"
#include "nwdbm.h" #include "nwdbm.h"
#if !CALL_NCPSERV_OVER_SOCKET
static struct pollfd polls[2]; static struct pollfd polls[2];
#endif
static int ncp_fd = -1; static int ncp_fd = -1;
static uint8 ipx_in_data[IPX_MAX_DATA+500]; /* space for additional data */ static uint8 ipx_in_data[IPX_MAX_DATA+500]; /* space for additional data */
static NCPREQUEST *ncprequest = (NCPREQUEST*)&ipx_in_data; static NCPREQUEST *ncprequest = (NCPREQUEST*)&ipx_in_data;
@ -32,6 +36,10 @@ static int rcv_flags = 0;
static char my_nwname[50]; static char my_nwname[50];
static time_t akttime; static time_t akttime;
static int server_goes_down=0; static int server_goes_down=0;
static int ipx_out_fd=-1;
/* next should be '1', is for testing only */
#define USE_PERMANENT_OUT_SOCKET 1
static void write_to_nwserv(int what, int connection, int mode, static void write_to_nwserv(int what, int connection, int mode,
char *data, int size) char *data, int size)
@ -58,7 +66,7 @@ static void write_to_nwserv(int what, int connection, int mode,
write(FD_NWSERV, &connection, sizeof(int)); write(FD_NWSERV, &connection, sizeof(int));
break; break;
case 0xffff : /* say nwserv to down the server */ case 0xffff : /* tell nwserv to down the server */
write(FD_NWSERV, &what, sizeof(int)); write(FD_NWSERV, &what, sizeof(int));
write(FD_NWSERV, &what, sizeof(int)); write(FD_NWSERV, &what, sizeof(int));
break; break;
@ -85,12 +93,12 @@ static void write_to_nwserv(int what, int connection, int mode,
#define nwserv_down_server() \ #define nwserv_down_server() \
write_to_nwserv(0xffff, 0, 0, NULL, 0) write_to_nwserv(0xffff, 0, 0, NULL, 0)
static int open_ncp_socket() static int open_ipx_sockets()
{ {
struct t_bind bind; struct t_bind bind;
ncp_fd=t_open("/dev/ipx", O_RDWR, NULL); ncp_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ncp_fd < 0) { if (ncp_fd < 0) {
if (nw_debug) t_error("t_open !Ok"); t_error("t_open !Ok");
return(-1); return(-1);
} }
U16_TO_BE16(SOCK_NCP, my_addr.sock); /* NCP_SOCKET */ U16_TO_BE16(SOCK_NCP, my_addr.sock); /* NCP_SOCKET */
@ -99,15 +107,30 @@ static int open_ncp_socket()
bind.addr.buf = (char*)&my_addr; bind.addr.buf = (char*)&my_addr;
bind.qlen = 0; /* immer */ bind.qlen = 0; /* immer */
if (t_bind(ncp_fd, &bind, &bind) < 0){ if (t_bind(ncp_fd, &bind, &bind) < 0){
if (nw_debug) t_error("t_bind in open_ncp_socket !OK"); t_error("t_bind in open_ipx_sockets !OK");
close(ncp_fd); close(ncp_fd);
return(-1); 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");
}
#endif
return(0); return(0);
} }
typedef struct { typedef struct {
int fd; /* writepipe */ int fd; /* writepipe */
/* or if CALL_NWCONN_OVER_SOCKET then sock_nr of nwconn */
int pid; /* pid from son */ int pid; /* pid from son */
ipxAddr_t client_adr; /* address client */ ipxAddr_t client_adr; /* address client */
uint32 object_id; /* logged object */ uint32 object_id; /* logged object */
@ -126,43 +149,53 @@ static int anz_connect=0; /* actual anz connections */
static int new_conn_nr(void) static int new_conn_nr(void)
{ {
int j = -1; int j = -1;
int one_found=0;
if (!anz_connect){ /* init all */ if (!anz_connect){ /* init all */
j = MAX_CONNECTIONS; j = MAX_CONNECTIONS;
while (j--) { while (j--) {
connections[j].fd = -1; connections[j].fd = -1;
connections[j].pid = -1;
connections[j].message[0] = '\0'; connections[j].message[0] = '\0';
} }
anz_connect++; anz_connect++;
return(1); return(1);
} }
j = -1; j = -1;
while (++j < MAX_CONNECTIONS) { while (++j < MAX_CONNECTIONS) {
CONNECTION *c=&(connections[j]); CONNECTION *c=&(connections[j]);
if (c->fd < 0) { if (c->fd < 0 && c->pid < 0) {
c->message[0] = '\0'; c->message[0] = '\0';
if (++j > anz_connect) anz_connect=j; if (++j > anz_connect) anz_connect=j;
return(j); return(j);
} }
} }
/* nothing free */ /* nothing free */
j=MAX_CONNECTIONS; j=MAX_CONNECTIONS;
while (j--) { while (j-- && one_found < 3) {
CONNECTION *c=&(connections[j]); CONNECTION *c=&(connections[j]);
if (!c->object_id) { /* NOT LOGGED IN */ if (!c->object_id) { /* NOT LOGGED IN */
/* makes wdog test faster */ /* makes wdog test faster */
nwserv_handle_wdog(j+1, 1); nwserv_handle_wdog(j+1, 1);
return(0); one_found++;
} }
} }
j=0;
while (j++ < MAX_CONNECTIONS) nwserv_handle_wdog(j, 2); if (!one_found) {
j=0;
while (j++ < MAX_CONNECTIONS)
nwserv_handle_wdog(j, 2); /* slow activate wdog */
}
return(0); /* nothing free */ return(0); /* nothing free */
} }
static int free_conn_nr(int nr) static int free_conn_nr(int nr)
{ {
if (nr && --nr < anz_connect) { if (nr && --nr < anz_connect) {
connections[nr].fd = -1; connections[nr].fd = -1;
connections[nr].pid = -1;
return(0); return(0);
} }
return(-1); return(-1);
@ -185,21 +218,43 @@ static void clear_connection(int conn)
if (conn > 0 && --conn < anz_connect) { if (conn > 0 && --conn < anz_connect) {
CONNECTION *c = &connections[conn]; CONNECTION *c = &connections[conn];
if (c->fd > -1) { if (c->fd > -1) {
#if !CALL_NWCONN_OVER_SOCKET
close(c->fd); close(c->fd);
#endif
c->fd = -1; c->fd = -1;
if (c->pid > -1) { if (c->pid > -1) kill(c->pid, SIGTERM); /* kill it */
kill(c->pid, SIGTERM); /* kill it */
c->pid = -1;
}
} }
c->object_id = 0; c->object_id = 0;
conn = anz_connect; }
}
static void kill_connections(void)
/* here the connections will really removed */
{
int conn;
int stat_loc;
int pid;
while ((pid=waitpid(-1, &stat_loc, WNOHANG)) > 0) {
conn = anz_connect;
while (conn--) { while (conn--) {
CONNECTION *c = &connections[conn]; CONNECTION *c = &connections[conn];
if (c->fd < 0) anz_connect--; if (c->pid == pid) clear_connection(conn+1);
else break;
} }
} }
conn = anz_connect;
while (conn--) {
CONNECTION *c = &connections[conn];
if (c->fd < 0 && c->pid > -1) {
kill(c->pid, SIGKILL); /* kill it */
c->pid = -1;
}
}
conn = anz_connect;
while (conn--) {
CONNECTION *c = &connections[conn];
if (c->fd < 0 && c->pid < 0) anz_connect--;
else break;
}
} }
static int find_get_conn_nr(ipxAddr_t *addr) static int find_get_conn_nr(ipxAddr_t *addr)
@ -214,6 +269,7 @@ static int find_get_conn_nr(ipxAddr_t *addr)
if (!connection){ if (!connection){
if ((connection = new_conn_nr()) > 0){ if ((connection = new_conn_nr()) > 0){
CONNECTION *c=&(connections[connection-1]); CONNECTION *c=&(connections[connection-1]);
#if !CALL_NWCONN_OVER_SOCKET
int fds[2]; int fds[2];
memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t)); memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t));
if (pipe(fds) < 0) { if (pipe(fds) < 0) {
@ -221,15 +277,50 @@ static int find_get_conn_nr(ipxAddr_t *addr)
free_conn_nr(connection); free_conn_nr(connection);
return(0); return(0);
} else { } else {
#else
int ipx_fd=-1;
struct t_bind bind;
memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t));
ipx_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ipx_fd > -1) {
U16_TO_BE16(0, my_addr.sock); /* actual write socket */
bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_addr;
bind.qlen = 0; /* allways */
if (t_bind(ipx_fd, &bind, &bind) < 0){
if (nw_debug) t_error("t_bind !OK");
t_close(ipx_fd);
ipx_fd = -1;
} else {
;
#if 0
t_unbind(ipx_fd);
t_close(ipx_fd);
ipx_fd = (int) GET_BE16(my_addr.sock);
#endif
}
} else {
if (nw_debug) t_error("t_open !Ok");
}
if (ipx_fd < 0) {
errorp(0, "find_get_conn_nr, socket", NULL);
free_conn_nr(connection);
return(0);
} else {
#endif
int akt_pid = getpid(); int akt_pid = getpid();
int pid = fork(); int pid = fork();
if (pid < 0) { if (pid < 0) {
errorp(0, "find_get_conn_nr, fork", NULL); errorp(0, "find_get_conn_nr, fork", NULL);
free_conn_nr(connection); free_conn_nr(connection);
#if !CALL_NWCONN_OVER_SOCKET
close(fds[0]); close(fds[0]);
close(fds[1]); close(fds[1]);
#endif
return(0); return(0);
} }
if (pid == 0) { if (pid == 0) {
/* new process */ /* new process */
char *progname="nwconn"; char *progname="nwconn";
@ -238,10 +329,14 @@ static int find_get_conn_nr(ipxAddr_t *addr)
char connstr[20]; char connstr[20];
char addrstr[100]; char addrstr[100];
int j = 2; int j = 2;
#if !CALL_NWCONN_OVER_SOCKET
close(fds[1]); /* no writing */ close(fds[1]); /* no writing */
dup2(fds[0], 0); /* becomes stdin */ dup2(fds[0], 0); /* becomes stdin */
close(fds[0]); /* not needed */ close(fds[0]); /* not needed */
#else
dup2(ipx_fd, 0); /* becomes stdin */
close(ipx_fd);
#endif
while (j++ < 100) close(j); /* close all > stderr */ while (j++ < 100) close(j); /* close all > stderr */
sprintf(pidstr, "%d", akt_pid); sprintf(pidstr, "%d", akt_pid);
@ -253,8 +348,13 @@ static int find_get_conn_nr(ipxAddr_t *addr)
exit(1); /* normaly not reached */ exit(1); /* normaly not reached */
} }
c->pid = pid; c->pid = pid;
#if CALL_NWCONN_OVER_SOCKET
c->fd = (int) GET_BE16(my_addr.sock);
close(ipx_fd);
#else
c->fd = fds[1]; c->fd = fds[1];
close(fds[0]); /* no need to read */ close(fds[0]); /* no need to read */
#endif
XDPRINTF((5,0, "AFTER FORK new PROCESS =%d, connection=%d", pid, connection)); XDPRINTF((5,0, "AFTER FORK new PROCESS =%d, connection=%d", pid, connection));
} }
} }
@ -290,6 +390,16 @@ static void get_login_time(uint8 login_time[], CONNECTION *cx)
login_time[6] = s_tm->tm_wday; login_time[6] = s_tm->tm_wday;
} }
#if CALL_NWCONN_OVER_SOCKET
static void send_to_nwconn(int nwconn_sock, char *data, int size)
{
ipxAddr_t nwconn_addr;
memcpy(&nwconn_addr, &my_addr, sizeof(ipxAddr_t));
U16_TO_BE16(nwconn_sock, nwconn_addr.sock);
send_ipx_data(ipx_out_fd, 17, size, data, &nwconn_addr, NULL);
}
#endif
static int handle_fxx(CONNECTION *c, int gelen, int func) static int handle_fxx(CONNECTION *c, int gelen, int func)
/* here are handled the global 0x15, 0x17, 0x57 functions */ /* here are handled the global 0x15, 0x17, 0x57 functions */
@ -426,7 +536,9 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
xdata->subversion = 15; xdata->subversion = 15;
} else { } else {
xdata->version = 3; xdata->version = 3;
xdata->subversion = 11; xdata->subversion = (tells_server_version == 2)
? 12
: 11;
} }
i=0; i=0;
@ -888,7 +1000,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
newpassword)); newpassword));
if (c->object_id == 1 || if (c->object_id == 1 ||
0 == (result=nw_test_unenpasswd(obj.id, oldpassword))) 0 == (result=nw_test_unenpasswd(obj.id, oldpassword)))
result=nw_set_passwd(obj.id, newpassword); result=nw_set_passwd(obj.id, newpassword, 0);
} }
if (result < 0) completition = (uint8) -result; if (result < 0) completition = (uint8) -result;
} else { } else {
@ -1232,10 +1344,16 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
ncpresponse->completition = completition; ncpresponse->completition = completition;
if (c->message[0]) connect_status |= 0x40; if (c->message[0]) connect_status |= 0x40;
ncpresponse->connect_status = connect_status; ncpresponse->connect_status = connect_status;
#if CALL_NWCONN_OVER_SOCKET
data_len+=sizeof(NCPRESPONSE);
send_to_nwconn(c->fd, (char*)ncpresponse, data_len);
#else
data_len=write(c->fd, (char*)ncpresponse, data_len=write(c->fd, (char*)ncpresponse,
sizeof(NCPRESPONSE) + data_len); sizeof(NCPRESPONSE) + data_len);
#endif
XDPRINTF((2, 0, "0x%x 0x%x compl:0x%x, write to %d, anz = %d", XDPRINTF((2, 0, "0x%x 0x%x compl:0x%x, write to %d, anz = %d",
func, (int)ufunc, (int) completition, c->fd, data_len)); func, (int)ufunc, (int) completition, c->fd, data_len));
return(0); /* ok */ return(0); /* ok */
} }
@ -1256,20 +1374,24 @@ static void ncp_response(int type, int sequence,
if (nw_debug){ if (nw_debug){
char comment[80]; char comment[80];
sprintf(comment, "NCP-RESP compl=0x%x ", completition); sprintf(comment, "NCP-RESP compl=0x%x ", completition);
send_ipx_data(-1, 17, sizeof(NCPRESPONSE) + data_len, send_ipx_data(ipx_out_fd, 17, sizeof(NCPRESPONSE) + data_len,
(char *) ncpresponse, (char *) ncpresponse,
&from_addr, comment); &from_addr, comment);
} else } else
send_ipx_data(-1, 17, sizeof(NCPRESPONSE) + data_len, send_ipx_data(ipx_out_fd, 17, sizeof(NCPRESPONSE) + data_len,
(char *) ncpresponse, (char *) ncpresponse,
&from_addr, NULL); &from_addr, NULL);
} }
#if 0
static void sig_child(int isig) static void sig_child(int isig)
{ {
int k=-1; int k=-1;
int status; int status;
int pid=wait(&status); int pid;
signal(SIGCHLD, sig_child);
pid=wait(&status);
XDPRINTF((1,0, "GOT conn pid=%d", pid));
if (pid > -1) { if (pid > -1) {
while (++k < anz_connect) { while (++k < anz_connect) {
CONNECTION *c = &connections[k]; CONNECTION *c = &connections[k];
@ -1278,9 +1400,10 @@ static void sig_child(int isig)
break; break;
} }
} }
kill(pid, SIGKILL); /* kill it */
} }
signal(SIGCHLD, sig_child);
} }
#endif
static void close_all(void) static void close_all(void)
{ {
@ -1291,20 +1414,32 @@ static void close_all(void)
t_close(ncp_fd); t_close(ncp_fd);
XDPRINTF((2,0, "LEAVE ncpserv")); XDPRINTF((2,0, "LEAVE ncpserv"));
ncp_fd = -1; ncp_fd = -1;
if (ipx_out_fd > -1) {
t_unbind(ipx_out_fd);
t_close(ipx_out_fd);
ipx_out_fd = -1;
}
} }
sync_dbm();
} }
static int server_is_down=0;
static void sig_quit(int isig) static void sig_quit(int isig)
{ {
close_all(); server_is_down++;
exit(0);
} }
static int got_sig_child=0;
static void sig_child(int isig)
{
got_sig_child++;
signal(SIGCHLD, sig_child);
}
static void set_sig(void) static void set_sig(void)
{ {
signal(SIGTERM, sig_quit);
signal(SIGQUIT, sig_quit); signal(SIGQUIT, sig_quit);
signal(SIGTERM, SIG_IGN);
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, sig_child); signal(SIGCHLD, sig_child);
@ -1323,7 +1458,7 @@ static void handle_bind_calls(uint8 *p)
p += 2; p += 2;
strmaxcpy(obj.name, p+1, *p); strmaxcpy(obj.name, p+1, *p);
p += (*p+1); p += (*p+1);
nw_new_create_prop(0, obj.name, obj.type, O_FL_DYNA, 0x40, nw_new_obj_prop(0, obj.name, obj.type, O_FL_DYNA, 0x40,
"NET_ADDRESS", P_FL_DYNA|P_FL_ITEM, 0x40, "NET_ADDRESS", P_FL_DYNA|P_FL_ITEM, 0x40,
(char *)p, sizeof(ipxAddr_t)); (char *)p, sizeof(ipxAddr_t));
} }
@ -1343,26 +1478,68 @@ static void handle_bind_calls(uint8 *p)
} }
} }
static int handle_ctrl(void) static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size)
/* reads stdin pipe */
{ {
if (*offs == 0) {
#if CALL_NCPSERV_OVER_SOCKET
memcpy(ipxd, &ipx_in_data, ud.udata.len);
#else
if (read(0, (char*)&(ipxd->owndata.d), sizeof(int)) == sizeof(int)) {
if (ipxd->owndata.d.size >= size &&
ipxd->owndata.d.size < IPX_MAX_DATA - sizeof(ipxd->owndata)) {
if (ipxd->owndata.d.size >
read(0, (char*)&(ipxd->owndata.d.function),
ipxd->owndata.d.size) ) {
size=-1;
}
} else {
errorp(1, "xread:", "datasize = %d", ipxd->owndata.d.size);
size=-1;
}
} else size = -1;
#endif
}
if (size > -1 && *offs + size > ipxd->owndata.d.size) {
errorp(1, "xread:", "prog error: *offs=%d + size=%d > d.size=%d",
*offs, size, ipxd->owndata.d.size);
size = -1;
}
if (size > -1) {
memcpy(data, ((uint8 *)&(ipxd->owndata.d.function)) + *offs, size);
*offs+=size;
} else {
errorp(1, "xread:", "readerror");
}
return(size);
}
static int handle_ctrl(void)
/* reads stdin pipe or packets from nwserv */
{
IPX_DATA ipxd;
int what; int what;
int conn; int conn;
int result = 0; int result = 0;
int data_len = read(0, (char*)&what, sizeof(what)); int offs=0;
if (data_len == sizeof(what)) { int data_len = xread(&ipxd, &offs, (uint8*)&(what), sizeof(int));
XDPRINTF((2, 0, "GOT CTRL what=0x%x", what)); if (data_len == sizeof(int)) {
XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd.owndata.d.size));
switch (what) { switch (what) {
case 0x5555 : /* clear_connection */ case 0x5555 : /* clear_connection */
data_len = read(0, (char*)&conn, sizeof(conn)); if (sizeof (int) ==
if (sizeof(int) == data_len) clear_connection(conn); xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int)))
clear_connection(conn);
break; break;
case 0x3333 : /* 'bindery' calls */ case 0x3333 : /* 'bindery' calls */
if (sizeof(conn) == read(0, (char*)&conn, sizeof(conn))) { if (sizeof (int) ==
xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) {
uint8 *buff = (uint8*) xmalloc(conn+10); uint8 *buff = (uint8*) xmalloc(conn+10);
XDPRINTF((2,0, "0x3333 len=%d", conn)); XDPRINTF((2,0, "0x3333 len=%d", conn));
if (conn == read(0, (char*)buff, conn)) if (conn == xread(&ipxd, &offs, buff, conn))
handle_bind_calls(buff); handle_bind_calls(buff);
else else
XDPRINTF((1, 1, "0x3333 protokoll error:len=%d", conn)); XDPRINTF((1, 1, "0x3333 protokoll error:len=%d", conn));
@ -1372,11 +1549,12 @@ static int handle_ctrl(void)
case 0xeeee: case 0xeeee:
get_ini_debug(NCPSERV); get_ini_debug(NCPSERV);
nw_fill_standard(NULL, NULL); (void)nw_fill_standard(NULL, NULL);
sync_dbm();
break; break;
case 0xffff : /* server down */ case 0xffff : /* server down */
data_len = read(0, (char*)&conn, sizeof(conn)); data_len = xread(&ipxd, &offs, (char*)&conn, sizeof(int));
if (sizeof(int) == data_len && conn == what) if (sizeof(int) == data_len && conn == what)
sent_down_message(); sent_down_message();
break; break;
@ -1384,27 +1562,175 @@ static int handle_ctrl(void)
default : break; default : break;
} /* switch */ } /* switch */
result++; result++;
} else XDPRINTF((2, 0, "GOT CTRL size=%d", data_len)); } else {
errorp(1, "handle_ctrl", "wrong data len=%d", data_len);
}
return(result); return(result);
} }
static void handle_ncp_request(void)
{
if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){
int type;
in_len = ud.udata.len;
time(&akttime);
XDPRINTF((10, 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 ( connection > 0 && connection <= anz_connect) {
CONNECTION *c = &(connections[connection-1]);
if (!memcmp(&from_addr, &(c->client_adr), sizeof(ipxAddr_t))) {
if (c->fd > -1){
if (type == 0x2222) {
int sent_here = 1;
int func = ncprequest->function;
int diff_time = akttime - c->last_access;
c->last_access = akttime;
if (diff_time > 50) /* after max. 50 seconds */
nwserv_reset_wdog(connection);
/* tell the wdog there's no need to look */
#if !CALL_NWCONN_OVER_SOCKET
if (ncprequest->sequence == c->sequence
&& !c->retry++) {
/* perhaps nwconn is busy */
ncp_response(0x9999, ncprequest->sequence,
connection, 0, 0x0, 0, 0);
XDPRINTF((2, 0, "Send Request being serviced to connection:%d", connection));
return;
}
#endif
switch (func) {
case 0x15 : /* Messages */
case 0x17 : /* File Server Environment */
sent_here = handle_fxx(c, in_len, func);
break;
case 0x57 : if (!tells_server_version) {
/* 2.15 er don't have namespace_calls */
sent_here = handle_fxx(c, in_len, func);
}
break;
default : break;
} /* switch */
if (sent_here) {
int anz=
#if CALL_NWCONN_OVER_SOCKET
in_len;
send_to_nwconn(c->fd, (char*)ncprequest, in_len);
#else
write(c->fd, (char*)ncprequest, in_len);
#endif
XDPRINTF((10,0, "write to %d, anz = %d", c->fd, anz));
if (func == 0x19) { /* logout */
c->object_id = 0; /* not LOGIN */
}
}
c->sequence = ncprequest->sequence; /* save last sequence */
c->retry = 0;
return;
} else { /* 0x5555, close connection */
#if !CALL_NWCONN_OVER_SOCKET
if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence)
#endif
{
clear_connection(ncprequest->connection);
ncp_response(0x3333,
ncprequest->sequence,
connection,
1, /* task */
0x0, /* completition */
0, /* conn status */
0);
return;
}
}
}
XDPRINTF((10,0, "c->fd = %d", c->fd));
}
}
/* here someting is wrong */
XDPRINTF((1,0, "GOT 0x%x connection=%d of %d conns not OK",
type, ncprequest->connection, anz_connect));
ncp_response(0x3333, ncprequest->sequence,
ncprequest->connection,
0, /* task */
0xff, /* completition */
0xff, /* conn status */
0);
} else if (type == 0x1111) {
/* GIVE CONNECTION Nr connection */
int connection = (server_goes_down) ? 0 : find_get_conn_nr(&from_addr);
XDPRINTF((2, 0, "GIVE CONNECTION NR=%d", connection));
if (connection) {
CONNECTION *c = &(connections[connection-1]);
int anz;
c->message[0] = '\0';
c->object_id = 0; /* firsttime set 0 for NOT LOGIN */
c->sequence = 0;
#if CALL_NWCONN_OVER_SOCKET
anz = in_len;
send_to_nwconn(c->fd, (char*)ncprequest, in_len);
#else
anz=write(c->fd, (char*)ncprequest, in_len);
#endif
XDPRINTF((10, 0, "write to oldconn %d, anz = %d", c->fd, anz));
} else /* no free connection */
ncp_response(0x3333, 0, 0, 0,
0xf9, /* completition */
0, /* conn status */
0);
#if CALL_NCPSERV_OVER_SOCKET
} else if (type == 0xeeee
&& ((OWN_DATA*)(&ipx_in_data))->type1[0] == 0xee
&& ((OWN_DATA*)(&ipx_in_data))->type1[1] == 0xee
&& IPXCMPNODE(from_addr.node, my_addr.node)
&& IPXCMPNET (from_addr.net, my_addr.net)) {
/* comes from nwserv */
handle_ctrl();
#endif
} else {
int connection = (int)ncprequest->connection;
int sequence = (int)ncprequest->sequence;
XDPRINTF((1,0, "Got UNKNOWN TYPE: 0x%x", type));
ncp_response(0x3333, sequence, connection,
1, 0xfb, 0, 0);
}
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int result;
int type;
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "usage ncpserv address nwname\n"); fprintf(stderr, "usage ncpserv address nwname\n");
exit(1); exit(1);
} }
init_tools(NCPSERV); init_tools(NCPSERV, 0);
strncpy(my_nwname, argv[1], 48); strncpy(my_nwname, argv[1], 48);
my_nwname[47] = '\0'; my_nwname[47] = '\0';
adr_to_ipx_addr(&my_addr, argv[2]); adr_to_ipx_addr(&my_addr, argv[2]);
nw_init_dbm(my_nwname, &my_addr);
if (nw_init_dbm(my_nwname, &my_addr) <0) {
errorp(1, "nw_init_dbm", NULL);
exit(1);
}
#ifdef LINUX #ifdef LINUX
set_emu_tli(); set_emu_tli();
#endif #endif
if (open_ncp_socket()) exit(1); if (open_ipx_sockets()) {
errorp(1, "open_ipx_sockets", NULL);
exit(1);
}
XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s",
(ipx_out_fd > -1) ? "enabled" : "disabled"));
ud.opt.len = sizeof(ipx_pack_typ); ud.opt.len = sizeof(ipx_pack_typ);
ud.opt.maxlen = sizeof(ipx_pack_typ); ud.opt.maxlen = sizeof(ipx_pack_typ);
ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual Typ */ ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual Typ */
@ -1418,133 +1744,32 @@ int main(int argc, char *argv[])
ud.udata.buf = (char*)&ipx_in_data; ud.udata.buf = (char*)&ipx_in_data;
set_sig(); set_sig();
#if CALL_NCPSERV_OVER_SOCKET
while (!server_is_down) {
handle_ncp_request();
if (got_sig_child) {
kill_connections();
got_sig_child=0;
}
}
#else
polls[0].events = polls[1].events = POLLIN|POLLPRI; polls[0].events = polls[1].events = POLLIN|POLLPRI;
polls[0].revents = polls[1].revents= 0; polls[0].revents = polls[1].revents= 0;
polls[0].fd = ncp_fd; polls[0].fd = ncp_fd;
polls[1].fd = 0; /* stdin */ polls[1].fd = 0; /* stdin */
while (1) { while (!server_is_down) {
int anz_poll = poll(polls, 2, 60000); int anz_poll = poll(polls, 2, 60000);
time(&akttime);
if (anz_poll > 0) { /* i have to work */ if (anz_poll > 0) { /* i have to work */
struct pollfd *p = &polls[0]; struct pollfd *p = &polls[0];
int j = -1; int j = -1;
while (++j < 2) { while (++j < 2) {
if (p->revents){ if (p->revents){
if (!j) { /* ncp-socket */ if (!j) { /* ncp-socket */
XDPRINTF((99,0, "POLL revents=%d", p->revents)); XDPRINTF((99,0, "POLL revents=%d", p->revents));
if (p->revents & ~POLLIN) if (p->revents & ~POLLIN)
errorp(0, "STREAM error", "revents=0x%x", p->revents ); errorp(0, "STREAM error", "revents=0x%x", p->revents );
else { else
if ((result = t_rcvudata(ncp_fd, &ud, &rcv_flags)) > -1){ handle_ncp_request();
in_len = ud.udata.len;
XDPRINTF((10, 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 ( connection > 0 && connection <= anz_connect) {
CONNECTION *c = &(connections[connection-1]);
if (!memcmp(&from_addr, &(c->client_adr), sizeof(ipxAddr_t))) {
if (c->fd > -1){
if (type == 0x2222) {
int sent_here = 1;
int func = ncprequest->function;
int diff_time = akttime - c->last_access;
c->last_access = akttime;
if (diff_time > 50) /* after max. 50 seconds */
nwserv_reset_wdog(connection);
/* tell the wdog there's no need to look */
if (ncprequest->sequence == c->sequence
&& !c->retry++) {
/* perhaps nwconn is busy */
ncp_response(0x9999, ncprequest->sequence,
connection, 0, 0x0, 0, 0);
XDPRINTF((2, 0, "Send Request being serviced to connection:%d", connection));
continue;
}
switch (func) {
case 0x15 : /* Messages */
case 0x17 : /* File Server Environment */
sent_here = handle_fxx(c, in_len, func);
break;
case 0x57 : if (!tells_server_version) {
/* 2.15 er has no namespace_calls */
sent_here = handle_fxx(c, in_len, func);
}
break;
default : break;
} /* switch */
if (sent_here) {
int anz=write(c->fd, (char*)ncprequest, in_len);
XDPRINTF((10,0, "write to %d, anz = %d", c->fd, anz));
if (func == 0x19) { /* logout */
c->object_id = 0; /* not LOGIN */
}
}
c->sequence = ncprequest->sequence; /* save last sequence */
c->retry = 0;
continue;
} else { /* 0x5555, close connection */
if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence) {
clear_connection(ncprequest->connection);
ncp_response(0x3333,
ncprequest->sequence,
connection,
1, /* task */
0x0, /* completition */
0, /* conn status */
0);
continue;
}
}
}
XDPRINTF((10,0, "c->fd = %d", c->fd));
}
}
/* here someting is wrong */
XDPRINTF((1,0, "GOT 0x%x connection=%d of %d conns not OK",
type, ncprequest->connection, anz_connect));
ncp_response(0x3333, ncprequest->sequence,
ncprequest->connection,
0, /* task */
0xff, /* completition */
0xff, /* conn status */
0);
} else if (type == 0x1111) {
/* GIVE CONNECTION Nr connection */
int connection = (server_goes_down) ? 0 : find_get_conn_nr(&from_addr);
XDPRINTF((2, 0, "GIVE CONNECTION NR=%d", connection));
if (connection) {
CONNECTION *c = &(connections[connection-1]);
int anz;
c->message[0] = '\0';
c->object_id = 0; /* firsttime set 0 for NOT LOGIN */
c->sequence = 0;
anz=write(c->fd, (char*)ncprequest, in_len);
XDPRINTF((10, 0, "write to oldconn %d, anz = %d", c->fd, anz));
} else /* no free connection */
ncp_response(0x3333, 0, 0, 0,
0xf9, /* completition */
0, /* conn status */
0);
} else {
int connection = (int)ncprequest->connection;
int sequence = (int)ncprequest->sequence;
XDPRINTF((1,0, "Got UNKNOWN TYPE: 0x%x", type));
ncp_response(0x3333, sequence, connection,
1, 0xfb, 0, 0);
}
}
}
} else if (p->fd==0) { /* fd_ncpserv_in */ } else if (p->fd==0) { /* fd_ncpserv_in */
XDPRINTF((2,0,"POLL %d, fh=%d", p->revents, p->fd)); XDPRINTF((2,0,"POLL %d, fh=%d", p->revents, p->fd));
if (p->revents & ~POLLIN) if (p->revents & ~POLLIN)
@ -1558,7 +1783,12 @@ int main(int argc, char *argv[])
} else { } else {
XDPRINTF((3,0,"POLLING ...")); XDPRINTF((3,0,"POLLING ..."));
} }
if (got_sig_child) {
kill_connections();
got_sig_child=0;
}
} }
#endif
close_all(); close_all();
return(0); return(0);
} }

29
net.h
View File

@ -1,4 +1,4 @@
/* net.h 11-Feb-96 */ /* net.h 01-Mar-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
@ -93,8 +93,25 @@
/* ===================> config.h <======================= */ /* ===================> config.h <======================= */
#ifdef CALL_NWCONN_OVER_SOCKET
# undef CALL_NWCONN_OVER_SOCKET
#endif
#ifdef CALL_NCPSERV_OVER_SOCKET
# undef CALL_NCPSERV_OVER_SOCKET
#endif
#include "config.h" #include "config.h"
#ifndef CALL_NWCONN_OVER_SOCKET
# define CALL_NWCONN_OVER_SOCKET 0
#endif
#ifndef CALL_NCPSERV_OVER_SOCKET
# define CALL_NCPSERV_OVER_SOCKET 1
#endif
#ifndef DO_DEBUG #ifndef DO_DEBUG
# define DO_DEBUG 1 # define DO_DEBUG 1
#endif #endif
@ -270,6 +287,15 @@ typedef union {
uint8 reserved; /* high connection */ uint8 reserved; /* high connection */
uint8 function; /* Function */ uint8 function; /* Function */
} ncprequest; } ncprequest;
struct S_OWN_DATA {
uint8 type[2]; /* 0xeeee */
uint8 type1[2]; /* 0xeeee */
struct {
int size; /* size of next two entries */
int function;
uint8 data[1];
} d;
} owndata;
char data[IPX_MAX_DATA]; char data[IPX_MAX_DATA];
} IPX_DATA; } IPX_DATA;
@ -283,6 +309,7 @@ typedef struct S_CONFREQ CONFREQ;
typedef struct S_DIAGRESP DIAGRESP; typedef struct S_DIAGRESP DIAGRESP;
typedef struct S_NCPRESPONSE NCPRESPONSE; typedef struct S_NCPRESPONSE NCPRESPONSE;
typedef struct S_NCPREQUEST NCPREQUEST; typedef struct S_NCPREQUEST NCPREQUEST;
typedef struct S_OWN_DATA OWN_DATA;
/* SOCKETS */ /* SOCKETS */
#define SOCK_AUTO 0x0000 /* Autobound Socket */ #define SOCK_AUTO 0x0000 /* Autobound Socket */

4
net1.c
View File

@ -108,7 +108,7 @@ void adr_to_ipx_addr(ipxAddr_t *p, char *s)
int net0, net1, net2, net3; int net0, net1, net2, net3;
int node0, node1, node2, node3, node4, node5; int node0, node1, node2, node3, node4, node5;
int sock0, sock1; int sock0, sock1;
sscanf(s, "%x.%x.%x.%x,%x.%x.%x.%x.%x.%x,%x.%x", sscanf(s, "%x.%x.%x.%x:%x.%x.%x.%x.%x.%x:%x.%x",
&net0, &net1, &net2, &net3, &net0, &net1, &net2, &net3,
&node0, &node1, &node2, &node3, &node4, &node5, &node0, &node1, &node2, &node3, &node4, &node5,
&sock0, &sock1); &sock0, &sock1);
@ -128,7 +128,7 @@ void adr_to_ipx_addr(ipxAddr_t *p, char *s)
void ipx_addr_to_adr(char *s, ipxAddr_t *p) void ipx_addr_to_adr(char *s, ipxAddr_t *p)
{ {
sprintf(s, "%x.%x.%x.%x,%x.%x.%x.%x.%x.%x,%x.%x", sprintf(s, "%x.%x.%x.%x:%x.%x.%x.%x.%x.%x:%x.%x",
(int)p->net[0] , (int)p->net[0] ,
(int)p->net[1] , (int)p->net[1] ,
(int)p->net[2] , (int)p->net[2] ,

34
netn.c
View File

@ -1,34 +0,0 @@
/* netr.c 11-Sep-95 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "net.h"
int main()
{
int ipx_fd = test1(SOCK_NCP);
if (ipx_fd > -1) {
if (t_unbind(ipx_fd) < 0){
t_error("t_unbind !OK");
}
t_close(ipx_fd);
}
return(0);
}

View File

@ -702,7 +702,7 @@ static void test_wdog(void)
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
init_tools(NWCLIENT); init_tools(NWCLIENT, 0);
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "usage: nwclient MY_ADDR SERVER_ADDR\n"); fprintf(stderr, "usage: nwclient MY_ADDR SERVER_ADDR\n");

124
nwconn.c
View File

@ -1,4 +1,4 @@
/* nwconn.c 10-Feb-96 */ /* nwconn.c 01-Mar-96 */
/* one process / connection */ /* one process / connection */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -44,7 +44,7 @@ static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff;
static uint8 *requestdata = readbuff + sizeof(NCPREQUEST); static uint8 *requestdata = readbuff + sizeof(NCPREQUEST);
static int ncp_type; static int ncp_type;
static int open_ipx_socket() static int open_ipx_socket(int wanted_sock)
{ {
struct t_bind bind; struct t_bind bind;
ipx_fd=t_open("/dev/ipx", O_RDWR, NULL); ipx_fd=t_open("/dev/ipx", O_RDWR, NULL);
@ -52,7 +52,7 @@ static int open_ipx_socket()
if (nw_debug) t_error("t_open !Ok"); if (nw_debug) t_error("t_open !Ok");
return(-1); return(-1);
} }
U16_TO_BE16(0, my_addr.sock); /* actual write socket */ U16_TO_BE16(wanted_sock, my_addr.sock); /* actual write socket */
bind.addr.len = sizeof(ipxAddr_t); bind.addr.len = sizeof(ipxAddr_t);
bind.addr.maxlen = sizeof(ipxAddr_t); bind.addr.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_addr; bind.addr.buf = (char*)&my_addr;
@ -67,9 +67,7 @@ static int open_ipx_socket()
return(0); return(0);
} }
static int req_printed=0; static int req_printed=0;
static int ncp_response(int sequence, static int ncp_response(int sequence,
int completition, int data_len) int completition, int data_len)
@ -1282,7 +1280,7 @@ extern int t_errno;
static void close_all(void) static void close_all(void)
{ {
nw_init_connect(); nw_exit_connect();
close(0); close(0);
if (ipx_fd > -1){ if (ipx_fd > -1){
while (t_unbind(ipx_fd) < 0) { while (t_unbind(ipx_fd) < 0) {
@ -1292,69 +1290,81 @@ static void close_all(void)
} }
} }
static int fl_get_int=0;
static void sig_quit(int rsig) static void sig_quit(int rsig)
{ {
close_all(); XDPRINTF((2, 0, "Got Signal=%d", rsig));
exit(0); fl_get_int=2;
}
static int fl_get_debug=0;
static void get_new_debug(void)
{
get_ini_debug(3);
fl_get_debug=0;
} }
static void sig_hup(int rsig) static void sig_hup(int rsig)
{ {
signal(SIGHUP, SIG_IGN); fl_get_int=1;
fl_get_debug++;
signal(SIGHUP, sig_hup); signal(SIGHUP, sig_hup);
} }
#if 0 static void get_new_debug(void)
static void sig_child(int isig)
{ {
int status; get_ini_debug(3);
int pid=wait(&status); fl_get_int=0;
if (pid > -1) kill(pid, SIGKILL); /* evtl Toechter killen */
signal(SIGCHLD, sig_child);
} }
#endif
static void set_sig(void) static void set_sig(void)
{ {
signal(SIGTERM, sig_quit); signal(SIGTERM, sig_quit);
signal(SIGQUIT, sig_quit); signal(SIGQUIT, sig_quit);
signal(SIGINT, sig_quit);
signal(SIGPIPE, sig_quit);
signal(SIGHUP, sig_hup); signal(SIGHUP, sig_hup);
signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
/* signal(SIGCHLD, sig_child); */
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
#if CALL_NWCONN_OVER_SOCKET
uint8 i_ipx_pack_typ;
ipxAddr_t x_from_addr;
ipxAddr_t client_addr;
struct t_unitdata iud;
#endif
int wanted_sock = (argc==5) ? atoi(*(argv+4)) : 0;
if (argc == 5) argc--;
if (argc != 4) { if (argc != 4) {
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection\n"); fprintf(stderr, "usage nwconn PID FROM_ADDR Connection [sock]\n");
exit(1); exit(1);
} else father_pid = atoi(*(argv+1)); } else father_pid = atoi(*(argv+1));
setuid(0); setuid(0);
setgid(0); setgid(0);
init_tools(NWCONN); init_tools(NWCONN, atoi(*(argv+3)));
XDPRINTF((1, 0, "FATHER PID=%d, ADDR=%s CON:%s", father_pid, *(argv+2), *(argv+3))); XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s", father_pid, *(argv+2), *(argv+3)));
adr_to_ipx_addr(&from_addr, *(argv+2)); adr_to_ipx_addr(&from_addr, *(argv+2));
#if CALL_NWCONN_OVER_SOCKET
adr_to_ipx_addr(&client_addr, *(argv+2));
#endif
if (nw_init_connect()) exit(1); if (nw_init_connect()) exit(1);
#ifdef LINUX #ifdef LINUX
set_emu_tli(); set_emu_tli();
#endif #endif
last_sequence = -9999; last_sequence = -9999;
if (open_ipx_socket()) exit(1); #if !CALL_NWCONN_OVER_SOCKET
if (open_ipx_socket(wanted_sock)) exit(1);
#else
ipx_fd =0;
# if 1
# ifdef SIOCIPXNCPCONN
{
int conn = atoi(*(argv+3));
int result = ioctl(ipx_fd, SIOCIPXNCPCONN, &conn);
XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result));
}
# endif
# endif
#endif
set_default_guid(); set_default_guid();
@ -1371,15 +1381,39 @@ int main(int argc, char **argv)
ncpresponse->reserved = (uint8) 0; /* allways 0 */ ncpresponse->reserved = (uint8) 0; /* allways 0 */
ncpresponse->connection = (uint8) atoi(*(argv+3)); ncpresponse->connection = (uint8) atoi(*(argv+3));
#if CALL_NWCONN_OVER_SOCKET
iud.opt.len = sizeof(i_ipx_pack_typ);
iud.opt.maxlen = sizeof(i_ipx_pack_typ);
iud.opt.buf = (char*)&i_ipx_pack_typ; /* gets actual Typ */
iud.addr.len = sizeof(ipxAddr_t);
iud.addr.maxlen = sizeof(ipxAddr_t);
iud.addr.buf = (char*)&x_from_addr;
iud.udata.len = IPX_MAX_DATA;
iud.udata.maxlen = IPX_MAX_DATA;
iud.udata.buf = (char*)readbuff;
#endif
set_sig(); set_sig();
while (1) { while (1) {
#if CALL_NWCONN_OVER_SOCKET
int rcv_flags = 0;
int data_len = (t_rcvudata(ipx_fd, &iud, &rcv_flags) > -1)
? iud.udata.len : -1;
#else
int data_len = read(0, readbuff, sizeof(readbuff)); int data_len = read(0, readbuff, sizeof(readbuff));
#endif
ncpresponse->connect_status = (uint8) 0; ncpresponse->connect_status = (uint8) 0;
if (data_len > 0) {
if (fl_get_debug) get_new_debug();
XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len));
if (fl_get_int) {
if (fl_get_int == 1) get_new_debug();
else if (fl_get_int == 2) break;
}
if (data_len > 0) {
XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len));
if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) { if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) {
/* OK for direct sending */ /* OK for direct sending */
data_len -= sizeof(NCPRESPONSE); data_len -= sizeof(NCPRESPONSE);
@ -1390,13 +1424,23 @@ int main(int argc, char **argv)
ncp_response((int)(ncprequest->sequence), (int)(ncprequest->function), data_len); ncp_response((int)(ncprequest->sequence), (int)(ncprequest->function), data_len);
} else { /* this calls I must handle */ } else { /* this calls I must handle */
requestlen = data_len - sizeof(NCPREQUEST); requestlen = data_len - sizeof(NCPREQUEST);
#if 0 /* CALL_NWCONN_OVER_SOCKET */
#ifdef SIOCIPXNCPCONN
if (ncp_type == 0x2222 &&
(0x17 == ncprequest->function || 0x15 == ncprequest->function)
&& IPXCMPSOCK (from_addr.sock, client_addr.sock)
&& IPXCMPNODE (from_addr.node, client_addr.node)
&& IPXCMPNET (from_addr.net, client_addr.net) {
/* this call must be prehandled by ncpserv */
XDPRINTF((2,0, "SEND TO NCPSERV"));
} else
#endif
#endif
handle_ncp_serv(); handle_ncp_serv();
} }
} else if (data_len < 0) {
if (fl_get_debug) get_new_debug();
else break;
} }
} } /* while */
close_all(); close_all();
XDPRINTF((2,0, "leave nwconn pid=%d", getpid()));
return(0); return(0);
} }

396
nwdbm.c
View File

@ -1,4 +1,4 @@
/* nwdbm.c 12-Feb-96 data base for mars_nwe */ /* nwdbm.c 22-Feb-96 data base for mars_nwe */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -36,18 +36,26 @@
# include <shadow.h> # include <shadow.h>
#endif #endif
#define DBM_REMAINS_OPEN 1
int tells_server_version=0; int tells_server_version=0;
int password_scheme=0; int password_scheme=0;
static char *fnprop = "nwprop";
static char *fnval = "nwval";
static char *fnobj = "nwobj";
static datum key; static datum key;
static datum data; static datum data;
static DBM *my_dbm=NULL; static DBM *my_dbm=NULL;
static int dbminit(char *s) #define FNPROP 0
#define FNVAL 1
#define FNOBJ 2
static char *dbm_fn[3] = { "nwprop", "nwval", "nwobj" };
#if DBM_REMAINS_OPEN
static DBM *my_dbms[3] = { NULL, NULL, NULL };
#endif
static int x_dbminit(char *s)
{ {
char buff[256]; char buff[256];
sprintf(buff, "%s/%s", PATHNAME_BINDERY, s); sprintf(buff, "%s/%s", PATHNAME_BINDERY, s);
@ -55,15 +63,45 @@ static int dbminit(char *s)
return( (my_dbm == NULL) ? -1 : 0); return( (my_dbm == NULL) ? -1 : 0);
} }
static int dbminit(int what_dbm)
{
#if DBM_REMAINS_OPEN
int result = 0;
if (NULL == my_dbms[what_dbm]) {
result = x_dbminit(dbm_fn[what_dbm]);
if (!result) my_dbms[what_dbm] = my_dbm;
} else my_dbm = my_dbms[what_dbm];
return(result);
#else
return(x_dbminit(dbm_fn[what_dbm]));
#endif
}
static int dbmclose() static int dbmclose()
{ {
if (my_dbm != NULL) { if (my_dbm != NULL) {
#if !DBM_REMAINS_OPEN
dbm_close(my_dbm); dbm_close(my_dbm);
#endif
my_dbm = NULL; my_dbm = NULL;
} }
return(0); return(0);
} }
void sync_dbm()
{
#if DBM_REMAINS_OPEN
int k = 3;
while (k--) {
if (NULL != my_dbms[k]) {
dbm_close(my_dbms[k]);
my_dbms[k] = NULL;
}
}
#endif
}
#define firstkey() dbm_firstkey(my_dbm) #define firstkey() dbm_firstkey(my_dbm)
#define nextkey(key) dbm_nextkey(my_dbm) #define nextkey(key) dbm_nextkey(my_dbm)
#define delete(key) dbm_delete(my_dbm, key) #define delete(key) dbm_delete(my_dbm, key)
@ -100,7 +138,7 @@ int find_obj_id(NETOBJ *o, uint32 last_obj_id)
XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x, lastid=0x%lx", XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x, lastid=0x%lx",
o->name, (int)o->type, last_obj_id)); o->name, (int)o->type, last_obj_id));
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
key = firstkey(); key = firstkey();
if (last_obj_id && (last_obj_id != MAX_U32)){ if (last_obj_id && (last_obj_id != MAX_U32)){
@ -142,7 +180,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
memset(xset, 0, sizeof(xset)); memset(xset, 0, sizeof(xset));
if (!prop_id) { if (!prop_id) {
XDPRINTF((2,0, "loc_delete_property obj_id=%d, prop=%s", obj_id, prop_name)); XDPRINTF((2,0, "loc_delete_property obj_id=%d, prop=%s", obj_id, prop_name));
if (!dbminit(fnprop)){ if (!dbminit(FNPROP)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
NETPROP *p=(NETPROP*)key.dptr; NETPROP *p=(NETPROP*)key.dptr;
if (p->obj_id == obj_id) { if (p->obj_id == obj_id) {
@ -163,7 +201,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
result = prop_id; result = prop_id;
} }
if (result > 0) { if (result > 0) {
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
int k; int k;
NETVAL val; NETVAL val;
key.dptr = (char*)&val; key.dptr = (char*)&val;
@ -182,7 +220,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
} else result=-0xff; } else result=-0xff;
dbmclose(); dbmclose();
if (result > 0) { if (result > 0) {
if (!dbminit(fnprop)){ /* now delete properties */ if (!dbminit(FNPROP)){ /* now delete properties */
int k; int k;
NETPROP prop; NETPROP prop;
key.dptr = (char*)&prop; key.dptr = (char*)&prop;
@ -209,7 +247,7 @@ static int loc_delete_obj(uint32 objid)
{ {
int result=0; int result=0;
(void)loc_delete_property(objid, (uint8*)"*", 0); (void)loc_delete_property(objid, (uint8*)"*", 0);
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
key.dptr = (char*)&objid; key.dptr = (char*)&objid;
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
if (delete(key)) result = -0xff; if (delete(key)) result = -0xff;
@ -232,7 +270,7 @@ int nw_rename_obj(NETOBJ *o, uint8 *newname)
int result = find_obj_id(o, 0); int result = find_obj_id(o, 0);
if (!result) { if (!result) {
result = -0xff; result = -0xff;
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o; key.dptr = (char*)o;
data = fetch(key); data = fetch(key);
@ -254,7 +292,7 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity)
int result = find_obj_id(o, 0); int result = find_obj_id(o, 0);
if (!result) { if (!result) {
result = -0xff; result = -0xff;
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o; key.dptr = (char*)o;
data = fetch(key); data = fetch(key);
@ -274,7 +312,7 @@ int nw_get_obj(NETOBJ *o)
{ {
int result = -0xfc; /* no Object */ int result = -0xfc; /* no Object */
XDPRINTF((2,0, "nw_get_obj von OBJ id = 0x%x", (int)o->id)); XDPRINTF((2,0, "nw_get_obj von OBJ id = 0x%x", (int)o->id));
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o; key.dptr = (char*)o;
data = fetch(key); data = fetch(key);
@ -294,7 +332,7 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id)
int result = -0xfb; /* no Property */ int result = -0xfb; /* no Property */
XDPRINTF((2,0, "find Prop id von name=0x%x:%s, lastid=%d", XDPRINTF((2,0, "find Prop id von name=0x%x:%s, lastid=%d",
obj_id, p->name, last_prop_id)); obj_id, p->name, last_prop_id));
if (!dbminit(fnprop)){ if (!dbminit(FNPROP)){
int flag = (last_prop_id) ? 0 : 1; int flag = (last_prop_id) ? 0 : 1;
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
NETPROP *prop=(NETPROP*)key.dptr; NETPROP *prop=(NETPROP*)key.dptr;
@ -325,7 +363,7 @@ static int loc_change_prop_security(NETPROP *p, uint32 obj_id)
{ {
int result = -0xfb; /* no Property */ int result = -0xfb; /* no Property */
XDPRINTF((2,0, "loc_change_prop_security Prop id von name=0x%x:%s", obj_id, p->name)); XDPRINTF((2,0, "loc_change_prop_security Prop id von name=0x%x:%s", obj_id, p->name));
if (!dbminit(fnprop)){ if (!dbminit(FNPROP)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
NETPROP *prop=(NETPROP*)key.dptr; NETPROP *prop=(NETPROP*)key.dptr;
if (prop->obj_id == obj_id) { if (prop->obj_id == obj_id) {
@ -357,7 +395,7 @@ static int loc_get_prop_val(uint32 obj_id, int prop_id, int segment,
{ {
int result = -0xec; /* no such Segment */ int result = -0xec; /* no such Segment */
NETVAL val; NETVAL val;
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE; key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val; key.dptr = (char*)&val;
val.obj_id = obj_id; val.obj_id = obj_id;
@ -384,7 +422,7 @@ int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id)
{ {
int result = -0xea; /* no such member */ int result = -0xea; /* no such member */
NETVAL val; NETVAL val;
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE; key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val; key.dptr = (char*)&val;
val.obj_id = obj_id; val.obj_id = obj_id;
@ -413,7 +451,7 @@ int prop_add_member(uint32 obj_id, int prop_id, uint32 member_id)
{ {
int result = 0; /* OK */ int result = 0; /* OK */
NETVAL val; NETVAL val;
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE; key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val; key.dptr = (char*)&val;
val.obj_id = obj_id; val.obj_id = obj_id;
@ -456,7 +494,7 @@ int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id)
{ {
int result = -0xea; /* no such member */ int result = -0xea; /* no such member */
NETVAL val; NETVAL val;
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE; key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val; key.dptr = (char*)&val;
val.obj_id = obj_id; val.obj_id = obj_id;
@ -492,7 +530,7 @@ int ins_prop_val(uint32 obj_id, uint8 prop_id, int segment,
uint8 *property_value, int erase_segments) uint8 *property_value, int erase_segments)
{ {
int result = -0xec; /* no such Segment */ int result = -0xec; /* no such Segment */
if (!dbminit(fnval)){ if (!dbminit(FNVAL)){
NETVAL val; NETVAL val;
int flag = 1; int flag = 1;
key.dsize = NETVAL_KEY_SIZE; key.dsize = NETVAL_KEY_SIZE;
@ -748,8 +786,12 @@ int nw_get_prop_val_str(uint32 q_id, char *propname, uint8 *buff)
{ {
uint8 more_segments; uint8 more_segments;
uint8 property_flags; uint8 property_flags;
int result=nw_get_prop_val_by_obj_id(q_id, 1, propname, strlen(propname), uint8 loc_buff[200];
int result;
if (NULL == buff) buff=loc_buff;
result=nw_get_prop_val_by_obj_id(q_id, 1, propname, strlen(propname),
buff, &more_segments, &property_flags); buff, &more_segments, &property_flags);
if (result > -1) { if (result > -1) {
result=strlen(buff); result=strlen(buff);
XDPRINTF((2,0, "nw_get_prop_val_str:%s strlen=%d", propname, result)); XDPRINTF((2,0, "nw_get_prop_val_str:%s strlen=%d", propname, result));
@ -768,7 +810,7 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id)
{ {
int result = 0; /* OK */ int result = 0; /* OK */
XDPRINTF((2,0, "creat OBJ=%s,type=0x%x", obj->name, (int)obj->type)); XDPRINTF((2,0, "creat OBJ=%s,type=0x%x", obj->name, (int)obj->type));
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key); data = fetch(key);
if (data.dptr){ if (data.dptr){
@ -801,7 +843,7 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id)
int nw_obj_has_prop(NETOBJ *obj) int nw_obj_has_prop(NETOBJ *obj)
{ {
int result = (dbminit(fnprop)) ? -0xff : 0; int result = (dbminit(FNPROP)) ? -0xff : 0;
if (!result){ if (!result){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
NETPROP *p=(NETPROP*)key.dptr; NETPROP *p=(NETPROP*)key.dptr;
@ -819,7 +861,7 @@ int nw_obj_has_prop(NETOBJ *obj)
int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop)
{ {
int result=0; int result=0;
if (!dbminit(fnprop)){ if (!dbminit(FNPROP)){
uint8 founds[256]; uint8 founds[256];
memset((char*)founds, 0, sizeof(founds) ); memset((char*)founds, 0, sizeof(founds) );
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
@ -853,7 +895,6 @@ int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop)
return(result); return(result);
} }
int nw_create_prop(int object_type, int nw_create_prop(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
uint8 *prop_name, int prop_namlen, uint8 *prop_name, int prop_namlen,
@ -876,35 +917,51 @@ int nw_create_prop(int object_type,
return(result); return(result);
} }
uint32 nw_new_create_prop(uint32 wanted_id, static int nw_new_obj(uint32 *wanted_id,
char *objname, int objtype,
int objflags, int objsecurity)
{
NETOBJ obj;
int result;
xstrcpy(obj.name, objname);
obj.type = (uint16) objtype;
obj.flags = (uint8) objflags;
obj.security = (uint8) objsecurity;
obj.id = 0L;
result = nw_create_obj(&obj, *wanted_id);
*wanted_id = obj.id;
return(result);
}
uint32 nw_new_obj_prop(uint32 wanted_id,
char *objname, int objtype, int objflags, int objsecurity, char *objname, int objtype, int objflags, int objsecurity,
char *propname, int propflags, int propsecurity, char *propname, int propflags, int propsecurity,
char *value, int valuesize) char *value, int valuesize)
/* /*
* creats new property value, if needed creats Object * creats new property value, if needed creats Object
* and the property, if valuesize == 0, then only obj or property * and the property,
* if propname == NULL only object will be created.
* if valuesize == 0, then only obj or property
* will be created, returns obj-id * will be created, returns obj-id
*/ */
{ {
NETOBJ obj; NETOBJ obj;
NETPROP prop; NETPROP prop;
if (objname && *objname){ if (objname && *objname)
strmaxcpy(obj.name, objname, sizeof(obj.name)); nw_new_obj(&wanted_id, objname, objtype,
obj.type = (uint8)objtype; objflags, objsecurity);
obj.flags = (uint8)objflags; obj.id = wanted_id;
obj.security = (uint8)objsecurity; if (propname && *propname) {
obj.id = 0; /* Erstmal */ strmaxcpy(prop.name, propname, sizeof(prop.name));
nw_create_obj(&obj, wanted_id); prop.flags = (uint8)propflags;
} else obj.id = wanted_id; prop.security = (uint8)propsecurity;
strmaxcpy(prop.name, propname, sizeof(prop.name)); nw_create_obj_prop(&obj, &prop);
prop.flags = (uint8)propflags; if (valuesize){
prop.security = (uint8)propsecurity; uint8 locvalue[128];
nw_create_obj_prop(&obj, &prop); memset(locvalue, 0, sizeof(locvalue));
if (valuesize){ memcpy(locvalue, value, min(sizeof(locvalue), valuesize));
uint8 locvalue[128]; ins_prop_val(obj.id, prop.id, 1, locvalue, 0xff);
memset(locvalue, 0, sizeof(locvalue)); }
memcpy(locvalue, value, min(sizeof(locvalue), valuesize));
ins_prop_val(obj.id, prop.id, 1, locvalue, 0xff);
} }
return(obj.id); return(obj.id);
} }
@ -1012,19 +1069,20 @@ int nw_test_unenpasswd(uint32 obj_id, uint8 *password)
} else return(-0xff); } else return(-0xff);
} }
int nw_set_enpasswd(uint32 obj_id, uint8 *passwd) static int nw_set_enpasswd(uint32 obj_id, uint8 *passwd, int dont_ch)
{ {
uint8 *prop_name=(uint8*)"PASSWORD"; uint8 *prop_name=(uint8*)"PASSWORD";
if (passwd && *passwd) { if (passwd && *passwd) {
nw_new_create_prop(obj_id, NULL, 0, 0, 0, if ((!dont_ch) || (nw_get_prop_val_str(obj_id, prop_name, NULL) < 1))
nw_new_obj_prop(obj_id, NULL, 0, 0, 0,
prop_name, P_FL_STAT|P_FL_ITEM, 0x44, prop_name, P_FL_STAT|P_FL_ITEM, 0x44,
passwd, 16); passwd, 16);
} else } else if (!dont_ch)
(void)loc_delete_property(obj_id, prop_name, 0); (void)loc_delete_property(obj_id, prop_name, 0);
return(0); return(0);
} }
int nw_set_passwd(uint32 obj_id, char *password) int nw_set_passwd(uint32 obj_id, char *password, int dont_ch)
{ {
if (password && *password) { if (password && *password) {
uint8 passwd[200]; uint8 passwd[200];
@ -1051,9 +1109,9 @@ int nw_set_passwd(uint32 obj_id, char *password)
(int)passwd[14], (int)passwd[14],
(int)passwd[15])); (int)passwd[15]));
#endif #endif
return(nw_set_enpasswd(obj_id, passwd)); return(nw_set_enpasswd(obj_id, passwd, dont_ch));
} else } else
return(nw_set_enpasswd(obj_id, NULL)); return(nw_set_enpasswd(obj_id, NULL, dont_ch));
} }
@ -1107,62 +1165,137 @@ static void add_pr_queue(uint32 q_id,
XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command)); XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command));
U32_TO_BE32(su_id, buff); U32_TO_BE32(su_id, buff);
q_id = q_id =
nw_new_create_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31, nw_new_obj_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31,
"Q_OPERATORS", P_FL_SET, 0x31, "Q_OPERATORS", P_FL_SET, 0x31,
(char*)buff, 4); (char*)buff, 4);
nw_new_create_prop(q_id ,NULL, 0 , 0 , 0 , nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 ,
"Q_DIRECTORY", P_FL_ITEM, 0x33, "Q_DIRECTORY", P_FL_ITEM, 0x33,
q_directory, strlen(q_directory)); q_directory, strlen(q_directory));
/* this is a own property to handler the print job !!! */ /* this is a own property to handler the print job !!! */
nw_new_create_prop(q_id ,NULL, 0 , 0 , 0 , nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 ,
"Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33, "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33,
q_command, strlen(q_command)); q_command, strlen(q_command));
U32_TO_BE32(ge_id, buff); U32_TO_BE32(ge_id, buff);
nw_new_create_prop(q_id , NULL, 0 , 0 , 0 , nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_USERS", P_FL_SET, 0x31, "Q_USERS", P_FL_SET, 0x31,
(char*)buff, 4); (char*)buff, 4);
#if 0 #if 0
nw_new_create_prop(q_id , NULL, 0 , 0 , 0 , nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_SERVERS", P_FL_SET, 0x31, "Q_SERVERS", P_FL_SET, 0x31,
NULL, 0); NULL, 0);
#endif #endif
} }
static void add_user_to_group(uint32 u_id, uint32 g_id)
static void add_user(uint32 u_id, uint32 g_id,
char *name, char *unname, char *password)
{ {
uint8 buff[4]; uint8 buff[4];
U32_TO_BE32(g_id, buff); U32_TO_BE32(g_id, buff);
u_id = /* Typ Flags Security */ /* Typ Flags Security */
nw_new_create_prop(u_id, name, 0x1 , 0x0, 0x33, nw_new_obj_prop(u_id, NULL, 0x1 , 0x0, 0x33,
"GROUPS_I'M_IN", P_FL_SET, 0x31, "GROUPS_I'M_IN", P_FL_SET, 0x31,
(char*)buff, 4); (char*)buff, 4);
nw_new_create_prop(u_id, NULL, 0 , 0 , 0 ,
"SECURITY_EQUALS", P_FL_SET, 0x32,
(char*)buff, 4);
nw_new_add_prop_member(g_id, "GROUP_MEMBERS", u_id); nw_new_add_prop_member(g_id, "GROUP_MEMBERS", u_id);
nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 ,
"SECURITY_EQUALS", P_FL_SET, 0x32,
(char*)buff, 4);
}
static void add_user(uint32 u_id, uint32 g_id,
char *name, char *unname,
char *password, int dont_ch)
{
/* Typ Flags Security */
if (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x33)
&& dont_ch) return;
XDPRINTF((1, 0, "Add/Change User='%s', UnixUser='%s'",
name, unname));
add_user_to_group(u_id, g_id);
if (unname && *unname) if (unname && *unname)
nw_new_create_prop(u_id, NULL, 0 , 0 , 0 , nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 ,
"UNIX_USER", P_FL_ITEM, 0x33, "UNIX_USER", P_FL_ITEM, 0x33,
(char*)unname, strlen(unname)); (char*)unname, strlen(unname));
if (password && *password) { if (password && *password) {
if (*password == '-') *password='\0'; if (*password == '-') *password='\0';
nw_set_passwd(u_id, password); nw_set_passwd(u_id, password, dont_ch);
} }
} }
void nw_fill_standard(char *servername, ipxAddr_t *adr) static void add_group(char *name, char *unname, char *password)
{
/* Typ Flags Security */
uint32 g_id = 0L;
(void) nw_new_obj(&g_id, name, 0x2 , 0x0, 0x31);
if (unname && *unname)
nw_new_obj_prop(g_id, NULL, 0 , 0 , 0 ,
"UNIX_GROUP", P_FL_ITEM, 0x33,
(char*)unname, strlen(unname));
}
static int get_sys_unixname(uint8 *unixname, uint8 *sysentry)
{
uint8 sysname[256];
char optionstr[256];
int founds = sscanf((char*)sysentry, "%s %s %s",sysname, unixname, optionstr);
if (founds > 1 && *unixname) {
struct stat statb;
int result = 0;
uint8 *pp = unixname + strlen(unixname);
if (founds > 2) {
uint8 *p;
for (p=optionstr; *p; p++) {
if (*p=='k') {
result=1;
break;
}
} /* for */
} /* if */
if (*(pp-1) != '/') *pp++ = '/';
*pp = '.';
*(pp+1) = '\0';
if (stat(unixname, &statb) < 0) {
errorp(1, "stat error:unix dir for SYS:", "fname='%s'", unixname);
return(-1);
}
*pp = '\0';
return(result);
} else return(-1);
}
static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int shorten,
int downshift, int permiss, int gid, int uid, char *fn)
{
struct stat stb;
strcpy((char*)pp, fn);
if (downshift) downstr(pp);
else upstr(pp);
if (stat(unixname, &stb) < 0) {
if (mkdir(unixname, 0777)< 0)
errorp(1, "mkdir error", "fname='%s'", unixname);
else {
chmod(unixname, permiss);
if (uid >-1 && gid > -1) chown(unixname, uid, gid);
XDPRINTF((1, 0, "Created dir '%s'", unixname));
}
}
if (shorten) *pp='\0';
else {
pp += strlen(pp);
*pp++='/';
*pp = '\0';
}
return(pp);
}
int nw_fill_standard(char *servername, ipxAddr_t *adr)
/* fills the Standardproperties */ /* fills the Standardproperties */
{ {
char serverna[MAX_SERVER_NAME+2]; char serverna[MAX_SERVER_NAME+2];
@ -1176,16 +1309,22 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
uint32 ngr_id = 0x0C000001; uint32 ngr_id = 0x0C000001;
uint32 ps1_id = 0x0D000001; uint32 ps1_id = 0x0D000001;
#endif #endif
FILE *f = open_nw_ini(); FILE *f = open_nw_ini();
ge_id = int auto_ins_user = 0;
nw_new_create_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31, char auto_ins_passwd[100];
"GROUP_MEMBERS", P_FL_SET, 0x31, int make_tests = 0;
NULL, 0); char sysentry[256];
sysentry[0] = '\0';
ge_id = nw_new_obj_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31,
"GROUP_MEMBERS", P_FL_SET, 0x31,
NULL, 0);
if (f){ if (f){
char buff[500]; char buff[256];
int what; int what;
while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) {
if (6 == what) { /* Server Version */ if (1 == what && !*sysentry) {
xstrcpy(sysentry, buff);
} if (6 == what) { /* Server Version */
tells_server_version = atoi(buff); tells_server_version = atoi(buff);
} else if (7 == what) { /* password_scheme */ } else if (7 == what) { /* password_scheme */
int pwscheme = atoi(buff); int pwscheme = atoi(buff);
@ -1232,7 +1371,8 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
add_pr_queue(q1_id, name, directory, command, su_id, ge_id); add_pr_queue(q1_id, name, directory, command, su_id, ge_id);
q1_id++; q1_id++;
} }
} else if (12 == what || 13 == what) { /* SUPERVISOR, OTHERS */ } else if (12 == what || 13 == what || 14 == what) {
/* SUPERVISOR, OTHERS and GROUPS*/
char nname[100]; char nname[100];
char uname[100]; char uname[100];
char password[100]; char password[100];
@ -1241,9 +1381,19 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
upstr(nname); upstr(nname);
if (anz > 2) upstr(password); if (anz > 2) upstr(password);
else password[0] = '\0'; else password[0] = '\0';
add_user((12 == what) ? su_id : 0L, ge_id, nname, if (what == 14)
uname, password); add_group(nname, uname, password);
else
add_user((12 == what) ? su_id : 0L, ge_id, nname,
uname, password, 0);
} }
} else if (15 == what) {
char buf[100];
int anz=sscanf((char*)buff, "%s %s", buf, auto_ins_passwd);
auto_ins_user = ((anz == 2) && atoi(buf) && *auto_ins_passwd);
if (auto_ins_user) auto_ins_user = atoi(buf);
} else if (16 == what) {
make_tests = atoi(buff);
} }
} /* while */ } /* while */
fclose(f); fclose(f);
@ -1251,13 +1401,73 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
if (servername && adr) { if (servername && adr) {
strmaxcpy(serverna, servername, MAX_SERVER_NAME); strmaxcpy(serverna, servername, MAX_SERVER_NAME);
upstr(serverna); upstr(serverna);
nw_new_create_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40,
"NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40,
(char*)adr, sizeof(ipxAddr_t)); (char*)adr, sizeof(ipxAddr_t));
} }
if (auto_ins_user) {
struct passwd *pw;
upstr(auto_ins_passwd);
while (NULL != (pw=getpwent())) {
char nname[100];
xstrcpy(nname, pw->pw_name);
upstr(nname);
add_user(0L, ge_id, nname, pw->pw_name, auto_ins_passwd,
(auto_ins_user == 99) ? 0 : 99);
}
endpwent();
}
if (*sysentry) {
int result = 0;
if (make_tests) {
uint8 unixname[512];
result = get_sys_unixname(unixname, sysentry);
if (result > -1) {
uint32 objs[2000]; /* max. 2000 User should be enough :) */
int ocount=0;
int downshift = (result & 1);
uint8 *pp = unixname+strlen(unixname);
uint8 *ppp;
test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "LOGIN");
test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "SYSTEM");
test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "PUBLIC");
ppp=test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "MAIL");
if (!dbminit(FNOBJ)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key);
if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr;
if (obj->type == 1) {
objs[ocount++] = obj->id;
if (ocount == 2000) break;
}
}
}
}
dbmclose();
while (ocount--) {
char sx[20];
int gid;
int uid;
sprintf(sx, "%lx", objs[ocount]);
if (!get_guid(&gid, &uid, objs[ocount]))
test_add_dir(unixname, ppp, 1, downshift, 0770, gid, uid, sx);
else {
NETOBJ obj;
obj.id = objs[ocount];
nw_get_obj(&obj);
errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name);
}
}
result = 0;
}
}
return(result);
}
return(-1);
} }
void nw_init_dbm(char *servername, ipxAddr_t *adr) int nw_init_dbm(char *servername, ipxAddr_t *adr)
/* /*
* routine inits bindery * routine inits bindery
* all dynamic objects and properties will be deletet. * all dynamic objects and properties will be deletet.
@ -1269,24 +1479,27 @@ void nw_init_dbm(char *servername, ipxAddr_t *adr)
uint32 objs[10000]; /* max.10000 Objekte */ uint32 objs[10000]; /* max.10000 Objekte */
uint8 props[10000]; /* max 10000 Properties */ uint8 props[10000]; /* max 10000 Properties */
create_nw_db(fnobj, 0); create_nw_db(dbm_fn[FNOBJ], 0);
create_nw_db(fnprop, 0); create_nw_db(dbm_fn[FNPROP], 0);
create_nw_db(fnval, 0); create_nw_db(dbm_fn[FNVAL], 0);
if (!dbminit(fnobj)){ if (!dbminit(FNOBJ)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key); data = fetch(key);
if (data.dptr) { if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr; NETOBJ *obj=(NETOBJ*)data.dptr;
if (obj->flags & O_FL_DYNA) /* Dynamisch */ if ((obj->flags & O_FL_DYNA) || !obj->name[0]) {
/* dynamic or without name */
objs[anz++] = obj->id; objs[anz++] = obj->id;
if (anz == 10000) break;
}
} }
} }
} }
dbmclose(); dbmclose();
while (anz--) loc_delete_obj(objs[anz]); /* Now delete */ while (anz--) loc_delete_obj(objs[anz]); /* Now delete */
anz = 0; anz = 0;
if (!dbminit(fnprop)){ if (!dbminit(FNPROP)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key); data = fetch(key);
if (data.dptr) { if (data.dptr) {
@ -1294,13 +1507,16 @@ void nw_init_dbm(char *servername, ipxAddr_t *adr)
if (prop->flags & P_FL_DYNA) { /* Dynamisch */ if (prop->flags & P_FL_DYNA) { /* Dynamisch */
objs[anz] = prop->obj_id; objs[anz] = prop->obj_id;
props[anz++] = prop->id; props[anz++] = prop->id;
if (anz == 10000) break;
} }
} }
} }
} }
dbmclose(); dbmclose();
while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz]); /* now delete */ while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz]); /* now delete */
nw_fill_standard(servername, adr); anz = nw_fill_standard(servername, adr);
sync_dbm();
return(anz);
} }
/* ============> this should becomes queue.c or similar < ============== */ /* ============> this should becomes queue.c or similar < ============== */

11
nwdbm.h
View File

@ -1,4 +1,4 @@
/* nwdbm.h 12-Feb-96 */ /* nwdbm.h 22-Feb-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -67,6 +67,7 @@ extern int password_scheme;
#define PW_SCHEME_LOGIN 2 #define PW_SCHEME_LOGIN 2
#define PW_SCHEME_GET_KEY_FAIL 4 #define PW_SCHEME_GET_KEY_FAIL 4
extern void sync_dbm(void);
extern int nw_get_prop(int object_type, extern int nw_get_prop(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
@ -171,7 +172,7 @@ extern int nw_create_prop(int object_type,
int prop_flags, int prop_security); int prop_flags, int prop_security);
extern uint32 nw_new_create_prop(uint32 wanted_id, extern uint32 nw_new_obj_prop(uint32 wanted_id,
char *objname, int objtype, int objflags, int objsecurity, char *objname, int objtype, int objflags, int objsecurity,
char *propname, int propflags, int propsecurity, char *propname, int propflags, int propsecurity,
char *value, int valuesize); char *value, int valuesize);
@ -180,11 +181,11 @@ extern int get_guid(int *gid, int *uid, uint32 obj_id);
extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key); extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key);
extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password); extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password);
extern int nw_set_passwd(uint32 obj_id, char *password); extern int nw_set_passwd(uint32 obj_id, char *password, int dont_ch);
extern int nw_get_q_dirname(uint32 q_id, uint8 *buff); extern int nw_get_q_dirname(uint32 q_id, uint8 *buff);
extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff); extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff);
extern void nw_fill_standard(char *servername, ipxAddr_t *adr); extern int nw_fill_standard(char *servername, ipxAddr_t *adr);
extern void nw_init_dbm(char *servername, ipxAddr_t *adr); extern int nw_init_dbm(char *servername, ipxAddr_t *adr);
#endif #endif

View File

@ -1,4 +1,4 @@
/* nwroute.c 08-Feb-96 */ /* nwroute.c 09-Mar-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -190,10 +190,12 @@ void insert_delete_server(uint8 *name, /* Server Name */
nr->hops = 0xffff; nr->hops = 0xffff;
} else if (do_delete) { } else if (do_delete) {
nr=nw_servers[k]; nr=nw_servers[k];
#if !FILE_SERVER_INACTIV #if !FILE_SERVER_INACTIV
if (!IPXCMPNODE(nr->addr.node, my_server_adr.node) || if (!IPXCMPNODE(nr->addr.node, my_server_adr.node) ||
!IPXCMPNET (nr->addr.net, my_server_adr.net) ) !IPXCMPNET (nr->addr.net, my_server_adr.net) )
#endif #endif
{ {
ins_del_bind_net_addr(nr->name, nr->typ, NULL); ins_del_bind_net_addr(nr->name, nr->typ, NULL);
xfree(nr->name); xfree(nr->name);
@ -394,7 +396,7 @@ void send_server_response(int respond_typ,
/* respond_typ 2 = general, 4 = nearest service respond */ /* respond_typ 2 = general, 4 = nearest service respond */
{ {
IPX_DATA ipx_data; IPX_DATA ipx_data;
int j=-1; int j=-1;
int tics=99; int tics=99;
int hops=15; int hops=15;
int entry = -1; int entry = -1;
@ -450,8 +452,14 @@ static void send_sap_broadcast(int mode)
U16_TO_BE16(SOCK_SAP, wild.sock); U16_TO_BE16(SOCK_SAP, wild.sock);
while (++j < anz_servers) { while (++j < anz_servers) {
NW_SERVERS *nw=nw_servers[j]; NW_SERVERS *nw=nw_servers[j];
if (!nw->typ || (nw->net == nd->net && nw->hops) if ( !nw->typ /* server has no typ */
|| (mode == 2 && nw->hops) ) continue; /* no SAP to this NET */ || ( nw->net == nd->net && nw->hops) /* server has same net but */
/* hops */
|| ( mode == 2 && nw->hops) ) { /* no SAP to this NET */
XDPRINTF((3, 0, "No SAP mode=%d, to net=0x%lx for server '%s'",
mode, nd->net, nw->name));
continue;
}
memset(&ipx_data, 0, sizeof(ipx_data.sip)); memset(&ipx_data, 0, sizeof(ipx_data.sip));
strcpy(ipx_data.sip.server_name, nw->name); strcpy(ipx_data.sip.server_name, nw->name);
memcpy(&ipx_data.sip.server_adr, &(nw->addr), sizeof(ipxAddr_t)); memcpy(&ipx_data.sip.server_adr, &(nw->addr), sizeof(ipxAddr_t));
@ -495,10 +503,10 @@ void send_sap_rip_broadcast(int mode)
/* mode=1, first trie */ /* mode=1, first trie */
/* mode=2, shutdown */ /* mode=2, shutdown */
{ {
static int flipflop=0; static int flipflop=1;
if (mode) { if (mode) {
send_sap_broadcast(mode);
send_rip_broadcast(mode); send_rip_broadcast(mode);
send_sap_broadcast(mode);
} else { } else {
if (flipflop) { if (flipflop) {
send_rip_broadcast(mode); send_rip_broadcast(mode);

229
nwserv.c
View File

@ -1,4 +1,4 @@
/* nwserv.c 10-Feb-96 */ /* nwserv.c 10-Mar-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -71,49 +71,81 @@ static struct pollfd polls[NEEDED_POLLS];
static uint16 spx_diag_socket; /* SPX DIAGNOSE SOCKET */ static uint16 spx_diag_socket; /* SPX DIAGNOSE SOCKET */
#endif #endif
static ipxAddr_t nw386_adr; /* Address of NW-TEST Server */ static ipxAddr_t nw386_adr; /* Address of NW-TEST Server */
static int nw386_found = 0; static int nw386_found = 0;
static int client_mode = 0; static int client_mode = 0;
static int ipxdebug = 0; static int ipxdebug = 0;
static int pid_ncpserv = -1; static int pid_ncpserv = -1;
#if !CALL_NCPSERV_OVER_SOCKET
static int fd_ncpserv_out = -1; /* ctrl-pipe out to ncpserv */ static int fd_ncpserv_out = -1; /* ctrl-pipe out to ncpserv */
#endif
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */ static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
static time_t akttime_stamp = 0; static time_t akttime_stamp = 0;
static int broadsecs = 2048; static int broadmillisecs = 2000; /* 2 sec */
static time_t server_down_stamp = 0; static time_t server_down_stamp = 0;
static int server_goes_down_secs = 10; static int server_goes_down_secs = 10;
static int server_broadcast_secs = 60;
static int save_ipx_routes = 0; static int save_ipx_routes = 0;
static uint8 *station_fn=NULL;
static int nearest_request_flag=0;
#if !FILE_SERVER_INACTIV #if !FILE_SERVER_INACTIV
static void add_wdata(IPX_DATA *d, char *data, int size)
{
memcpy(d->owndata.d.data+d->owndata.d.size, data, size);
d->owndata.d.size+=size;
}
static void write_wdata(IPX_DATA *d, int what)
{
#if CALL_NCPSERV_OVER_SOCKET
ipxAddr_t toaddr;
#endif
d->owndata.d.function=what;
d->owndata.d.size +=sizeof(int);
#if CALL_NCPSERV_OVER_SOCKET
memset(d->owndata.type, 0xee, 4);
memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t));
U16_TO_BE16(SOCK_NCP, toaddr.sock);
send_ipx_data(-1, 17,
4 + sizeof(int)+d->owndata.d.size, (char*)d,
&toaddr, "TO NCPSERV");
#else
write(fd_ncpserv_out, (char*) &(d->owndata.d),
sizeof(int)+d->owndata.d.size);
#endif
d->owndata.d.size=0;
}
static void write_to_ncpserv(int what, int connection, static void write_to_ncpserv(int what, int connection,
char *data, int data_size) char *data, int data_size)
{ {
IPX_DATA ipxd;
ipxd.owndata.d.size = 0;
XDPRINTF((2, 0, "write_to_ncpserv what=0x%x, conn=%d, data_size=%d", XDPRINTF((2, 0, "write_to_ncpserv what=0x%x, conn=%d, data_size=%d",
what, connection, data_size)); what, connection, data_size));
switch (what) { switch (what) {
case 0x5555 : /* kill connection */ case 0x5555 : /* kill connection */
write(fd_ncpserv_out, (char*) &what, sizeof(int)); add_wdata(&ipxd, (char*) &connection, sizeof(int));
write(fd_ncpserv_out, (char*) &connection, sizeof(int));
break; break;
case 0x3333 : /* 'bindery' calls */ case 0x3333 : /* 'bindery' calls */
write(fd_ncpserv_out, (char*) &what, sizeof(int)); add_wdata(&ipxd, (char*)&data_size, sizeof(int));
write(fd_ncpserv_out, (char*) &data_size, sizeof(int)); add_wdata(&ipxd, data, data_size);
write(fd_ncpserv_out, data, data_size);
break; break;
case 0xeeee : /* hup, read init */ case 0xeeee : /* hup, read init */
write(fd_ncpserv_out, (char*) &what, sizeof(int));
break; break;
case 0xffff : /* 'down server' */ case 0xffff : /* 'down server' */
write(fd_ncpserv_out, (char*) &what, sizeof(int)); add_wdata(&ipxd, (char*) &what, sizeof(int));
write(fd_ncpserv_out, (char*) &what, sizeof(int));
break; break;
default : break; default : return;
} }
write_wdata(&ipxd, what);
} }
#else #else
static void write_to_ncpserv(int what, int connection, static void write_to_ncpserv(int what, int connection,
@ -180,11 +212,15 @@ static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode)
static int start_ncpserv(char *nwname, ipxAddr_t *addr) static int start_ncpserv(char *nwname, ipxAddr_t *addr)
{ {
#if !FILE_SERVER_INACTIV #if !FILE_SERVER_INACTIV
#if !CALL_NCPSERV_OVER_SOCKET
int fds_out[2]; int fds_out[2];
#endif
int fds_in[2]; int fds_in[2];
int pid; int pid;
if (pipe(fds_out) < 0 || pipe(fds_in) < 0) return(-1); #if !CALL_NCPSERV_OVER_SOCKET
if (pipe(fds_out) < 0) return(-1);
#endif
if (pipe(fds_in) < 0) return(-1);
switch (pid=fork()) { switch (pid=fork()) {
case 0 : { /* new Process */ case 0 : { /* new Process */
@ -192,10 +228,11 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
char addrstr[100]; char addrstr[100];
char pathname[300]; char pathname[300];
int j = FD_NWSERV; int j = FD_NWSERV;
#if !CALL_NCPSERV_OVER_SOCKET
close(fds_out[1]); /* no need to write */ close(fds_out[1]); /* no need to write */
dup2(fds_out[0], 0); /* becommes stdin */ dup2(fds_out[0], 0); /* becommes stdin */
close(fds_out[0]); /* no longer needed */ close(fds_out[0]); /* no longer needed */
#endif
close(fds_in[0]); /* no need to read */ close(fds_in[0]); /* no need to read */
dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */ dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */
close(fds_in[1]); /* no longer needed */ close(fds_in[1]); /* no longer needed */
@ -207,14 +244,19 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
} }
break; break;
case -1: close(fds_out[0]); case -1:
#if !CALL_NCPSERV_OVER_SOCKET
close(fds_out[0]);
close(fds_out[1]); close(fds_out[1]);
#endif
close(fds_in[0]); close(fds_in[0]);
close(fds_in[1]); close(fds_in[1]);
return(-1); /* error */ return(-1); /* error */
} }
#if !CALL_NCPSERV_OVER_SOCKET
fds_out[0] = -1; fds_out[0] = -1;
fd_ncpserv_out = fds_out[1]; fd_ncpserv_out = fds_out[1];
#endif
fds_in[1] = -1; fds_in[1] = -1;
fd_ncpserv_in = fds_in[0]; fd_ncpserv_in = fds_in[0];
pid_ncpserv = pid; pid_ncpserv = pid;
@ -243,8 +285,11 @@ static int start_nwclient(void)
} }
/* =========================== WDOG =============================== */ /* =========================== WDOG =============================== */
#ifndef _WDOG_TESTING_
#define _WDOG_TESTING_ 0
#endif
#ifdef _WDOG_TESTING_ #if _WDOG_TESTING_
/* for testing */ /* for testing */
# define WDOG_TRIE_AFTER_SEC 1 # define WDOG_TRIE_AFTER_SEC 1
# define MAX_WDOG_TRIES 1 # define MAX_WDOG_TRIES 1
@ -314,15 +359,13 @@ static void modify_wdog_conn(int conn, int mode)
if (mode < 99) { if (mode < 99) {
c->last_time = akttime_stamp; c->last_time = akttime_stamp;
switch (mode) { switch (mode) {
case 1 : c->counter = MAX_WDOG_TRIES; /* quick test */ case 1 : c->counter = MAX_WDOG_TRIES; /* quick test */
broadsecs = 4096;
break; break;
case 2 : c->counter = 1; /* slow test (activate)*/ case 2 : c->counter = max(2, MAX_WDOG_TRIES); /* slow test (activate)*/
broadsecs = 4096;
break; break;
default : c->counter = 0; /* reset */ default : c->counter = 0; /* reset */
break; break;
} /* switch */ } /* switch */
} else if (mode == 99) { /* remove */ } else if (mode == 99) { /* remove */
@ -338,14 +381,15 @@ static void modify_wdog_conn(int conn, int mode)
} }
} }
static void send_wdogs(void) static void send_wdogs(int force)
{ {
int k = hi_conn; int k = hi_conn;
while (k--) { while (k--) {
CONN *c = &(conns[k]); CONN *c = &(conns[k]);
if (c->last_time) { if (c->last_time) {
time_t t_diff = akttime_stamp - c->last_time; time_t t_diff = akttime_stamp - c->last_time;
if (c->counter || t_diff > WDOG_TRIE_AFTER_SEC) { /* max. 5 minutes */ if ( (c->counter && (t_diff > 50 || force))
|| t_diff > WDOG_TRIE_AFTER_SEC) { /* max. 5 minutes */
if (c->counter > MAX_WDOG_TRIES) { if (c->counter > MAX_WDOG_TRIES) {
/* now its enough with trying */ /* now its enough with trying */
/* clear connection */ /* clear connection */
@ -389,6 +433,61 @@ void get_server_data(char *name,
XDPRINTF((2,0,"NW386 %s found at:%s", name, visable_ipx_adr(adr))); XDPRINTF((2,0,"NW386 %s found at:%s", name, visable_ipx_adr(adr)));
} }
static int name_match(uint8 *s, uint8 *p)
{
uint8 pc;
while ( (pc = *p++) != 0){
switch (pc) {
case '?' : if (!*s++) return(0); /* simple char */
break;
case '*' : if (!*p) return(1); /* last star */
while (*s) {
if (name_match(s, p) == 1) return(1);
++s;
}
return(0);
default : if (pc != *s++) return(0); /* normal char */
break;
} /* switch */
} /* while */
return ( (*s) ? 0 : 1);
}
static int find_station_match(int entry, ipxAddr_t *addr)
{
int matched = 0;
if (station_fn && *station_fn) {
FILE *f=fopen(station_fn, "r");
if (f) {
char buff[200];
char addrstring[100];
int what;
ipx_addr_to_adr(addrstring, addr);
upstr(addrstring);
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))){
if (what == entry) {
char *p = buff + strlen(buff);
while (p-- > buff && *p==32) *p='\0';
upstr(buff);
if (name_match(addrstring, buff)) {
matched=1;
break;
}
}
}
fclose(f);
} else {
XDPRINTF((3, 0, "find_station_match, cannot open '%s'",
station_fn));
}
}
XDPRINTF((3, 0, "find_station_match entry=%d, matched=%d, addr=%s",
entry, matched, visable_ipx_adr(addr)));
return(matched);
}
static void handle_sap(int fd, static void handle_sap(int fd,
int ipx_pack_typ, int ipx_pack_typ,
int data_len, int data_len,
@ -402,7 +501,19 @@ static void handle_sap(int fd,
XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d von %s", XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d von %s",
server_type, visable_ipx_adr(from_addr))); server_type, visable_ipx_adr(from_addr)));
/* Get Nearest File Server */ /* Get Nearest File Server */
send_server_response(4, server_type, from_addr); if (!nearest_request_flag)
send_server_response(4, server_type, from_addr);
#if INTERNAL_RIP_SAP
else {
int do_sent = (nearest_request_flag == 1) ? 1 : 0;
if (find_station_match(1, from_addr)) do_sent = !do_sent;
if (do_sent)
send_server_response(4, server_type, from_addr);
XDPRINTF((3,0, "SAP NEAREST REQUEST =%d, nearest_request_flag=%d",
do_sent, nearest_request_flag));
}
#endif
} else if (query_type == 1) { /* general Request */ } else if (query_type == 1) { /* general Request */
XDPRINTF((2,0, "SAP GENERAL request server_type =%d", server_type)); XDPRINTF((2,0, "SAP GENERAL request server_type =%d", server_type));
send_server_response(2, server_type, from_addr); send_server_response(2, server_type, from_addr);
@ -755,6 +866,12 @@ static void get_ini(int full)
server_goes_down_secs = 10; server_goes_down_secs = 10;
break; break;
case 211 : server_broadcast_secs=atoi(inhalt);
if (server_broadcast_secs < 10 ||
server_broadcast_secs > 600)
server_broadcast_secs = 60;
break;
case 300 : print_route_tac=atoi(inhalt); case 300 : print_route_tac=atoi(inhalt);
break; break;
@ -767,6 +884,12 @@ static void get_ini(int full)
case 310 : wdogs_till_tics=atoi(inhalt); case 310 : wdogs_till_tics=atoi(inhalt);
break; break;
case 400 : new_str(station_fn, (uint8*)inhalt);
break;
case 401 : nearest_request_flag=atoi(inhalt);
break;
default : break; default : break;
} /* switch */ } /* switch */
} /* if */ } /* if */
@ -777,6 +900,11 @@ static void get_ini(int full)
if (print_route_tac && !pr_route_info_fn && !*pr_route_info_fn) if (print_route_tac && !pr_route_info_fn && !*pr_route_info_fn)
print_route_tac = 0; print_route_tac = 0;
if (!print_route_tac) xfree(pr_route_info_fn); if (!print_route_tac) xfree(pr_route_info_fn);
#if INTERNAL_RIP_SAP
server_broadcast_secs /= 2;
#endif
if (full) { if (full) {
#ifdef LINUX #ifdef LINUX
# if INTERNAL_RIP_SAP # if INTERNAL_RIP_SAP
@ -828,15 +956,17 @@ static void close_all(void)
if (pid_ncpserv > 0) { if (pid_ncpserv > 0) {
int status; int status;
#if !CALL_NCPSERV_OVER_SOCKET
if (fd_ncpserv_out > -1) { if (fd_ncpserv_out > -1) {
close(fd_ncpserv_out); close(fd_ncpserv_out);
fd_ncpserv_out =-1; fd_ncpserv_out =-1;
} }
#endif
if (fd_ncpserv_in > -1) { if (fd_ncpserv_in > -1) {
close(fd_ncpserv_in); close(fd_ncpserv_in);
fd_ncpserv_in = -1; fd_ncpserv_in = -1;
} }
kill(pid_ncpserv, SIGTERM); /* terminate ncpserv */ kill(pid_ncpserv, SIGQUIT); /* terminate ncpserv */
waitpid(pid_ncpserv, &status, 0); waitpid(pid_ncpserv, &status, 0);
kill(pid_ncpserv, SIGKILL); /* kill ncpserv */ kill(pid_ncpserv, SIGKILL); /* kill ncpserv */
} }
@ -869,7 +999,7 @@ static void down_server(void)
fprintf(stderr, "\n*********************************************\n"); fprintf(stderr, "\n*********************************************\n");
sleep(1); sleep(1);
fprintf(stderr, "\007\n"); fprintf(stderr, "\007\n");
broadsecs=100; broadmillisecs = 100;
server_down_stamp = akttime_stamp; server_down_stamp = akttime_stamp;
send_down_broadcast(); send_down_broadcast();
} }
@ -908,6 +1038,8 @@ static void set_sigs(void)
signal(SIGHUP, sig_hup); signal(SIGHUP, sig_hup);
} }
static int server_is_down=0;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int j = -1; int j = -1;
@ -915,7 +1047,7 @@ int main(int argc, char **argv)
if (argc > 1) client_mode=1; if (argc > 1) client_mode=1;
/* in client mode the testprog 'nwclient' will be startet. */ /* in client mode the testprog 'nwclient' will be startet. */
init_tools(NWSERV); init_tools(NWSERV, 0);
get_ini(1); get_ini(1);
while (++j < NEEDED_POLLS) { while (++j < NEEDED_POLLS) {
@ -955,12 +1087,12 @@ int main(int argc, char **argv)
&my_server_adr, &server_adr_sap, 0, 0, 0); &my_server_adr, &server_adr_sap, 0, 0, 0);
} }
#endif #endif
while (!server_is_down) {
while (1) { int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs);
int anz_poll = poll(polls, NEEDED_POLLS, broadsecs); int call_wdog=0;
time(&akttime_stamp); time(&akttime_stamp);
if (fl_get_int) { if (fl_get_int) {
if (fl_get_int == 1) handle_hup_reqest(); if (fl_get_int == 1) handle_hup_reqest();
else if (fl_get_int == 2) down_server(); else if (fl_get_int == 2) down_server();
} }
if (anz_poll > 0) { /* i have to work */ if (anz_poll > 0) { /* i have to work */
@ -1006,6 +1138,7 @@ int main(int argc, char **argv)
&& sizeof(int) == read(fd_ncpserv_in, && sizeof(int) == read(fd_ncpserv_in,
(char*)&what, sizeof(what))) (char*)&what, sizeof(what)))
modify_wdog_conn(conn, what); modify_wdog_conn(conn, what);
if (what > 0 && what < 99) call_wdog++;
break; break;
case 0x6666 : /* bcast message */ case 0x6666 : /* bcast message */
@ -1035,25 +1168,29 @@ int main(int argc, char **argv)
} else { } else {
XDPRINTF((99,0,"POLLING ...")); XDPRINTF((99,0,"POLLING ..."));
} }
if (server_down_stamp) { if (server_down_stamp) {
if (akttime_stamp - server_down_stamp > server_goes_down_secs) break; if (akttime_stamp - server_down_stamp > server_goes_down_secs)
server_is_down++;
} else { } else {
if (akttime_stamp - broadtime > (broadsecs / 1000)) { /* ca. 30 seconds */ int bsecs = broadmillisecs / 1000;
send_sap_rip_broadcast((broadsecs<3000) ? 1 :0); /* firsttime broadcast */ int difftime = akttime_stamp - broadtime;
if (broadsecs < 30000) { if (difftime > bsecs) {
send_sap_rip_broadcast((bsecs < 3) ? 1 : 0); /* firsttime broadcast */
if (bsecs < server_broadcast_secs) {
rip_for_net(MAX_U32); rip_for_net(MAX_U32);
get_servers(); get_servers();
broadsecs *= 2; bsecs *= 2;
if (broadsecs > 30000) if (bsecs > server_broadcast_secs)
#if INTERNAL_RIP_SAP bsecs=server_broadcast_secs;
broadsecs = 30000; /* every 30 sec. */ broadmillisecs = bsecs*1000+10;
#else
broadsecs = 60000; /* every 60 sec. */
#endif
} }
send_wdogs(); send_wdogs(call_wdog);
broadtime = akttime_stamp; broadtime = akttime_stamp;
} else if (client_mode) get_servers(); /* Here more often */ } else {
if (call_wdog) send_wdogs(1);
if (client_mode && difftime > 5) get_servers(); /* Here more often */
}
} }
} /* while */ } /* while */
send_down_broadcast(); send_down_broadcast();

44
tools.c
View File

@ -1,4 +1,4 @@
/* tools.c 22-Jan-96 */ /* tools.c 09-Mar-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -29,7 +29,8 @@ extern char _sys_errlist[];
int nw_debug=0; int nw_debug=0;
FILE *logfile=stdout; FILE *logfile=stdout;
static int in_module=0; /* in which process i am ? */ static int in_module=0; /* in which process i am ? */
static int connection=0; /* which connection (nwconn) */
static char *modnames[] = static char *modnames[] =
{ "???????", { "???????",
"NWSERV ", "NWSERV ",
@ -46,7 +47,7 @@ char *xmalloc(uint size)
{ {
char *p = (size) ? (char *)malloc(size) : (char*)NULL; char *p = (size) ? (char *)malloc(size) : (char*)NULL;
if (p == (char *)NULL && size){ if (p == (char *)NULL && size){
fprintf(logfile, "not enough core, need %d Bytes\n", size); errorp(1, "xmalloc", "not enough core, need %d Bytes\n", size);
exit(1); exit(1);
} }
return(p); return(p);
@ -67,7 +68,7 @@ void x_x_xfree(char **p)
} }
} }
int strmaxcpy(uint8 *dest, uint8 *source, int len) int strmaxcpy(uint8 *dest, uint8 *source, int len)
{ {
int slen = (source != (uint8 *)NULL) ? min(len, strlen((char*)source)) : 0; int slen = (source != (uint8 *)NULL) ? min(len, strlen((char*)source)) : 0;
if (slen) memcpy(dest, source, slen); if (slen) memcpy(dest, source, slen);
@ -103,7 +104,7 @@ void xdprintf(int dlevel, int mode, char *p, ...)
{ {
va_list ap; va_list ap;
if (nw_debug >= dlevel) { if (nw_debug >= dlevel) {
if (!(mode & 1)) fprintf(logfile, "%s:", get_modstr()); if (!(mode & 1)) fprintf(logfile, "%s %d:", get_modstr(), connection);
if (p) { if (p) {
va_start(ap, p); va_start(ap, p);
vfprintf(logfile, p, ap); vfprintf(logfile, p, ap);
@ -117,18 +118,24 @@ void xdprintf(int dlevel, int mode, char *p, ...)
void errorp(int mode, char *what, char *p, ...) void errorp(int mode, char *what, char *p, ...)
{ {
va_list ap; va_list ap;
int errnum = errno; int errnum = errno;
if (errnum >= 0 && errnum < _sys_nerr) FILE *lologfile = logfile;
fprintf(logfile, "%s:%s:%s\n", get_modstr(), what, _sys_errlist[errnum]); while (1) {
else if (mode) fprintf(lologfile, "\n!! %s %d:PANIC !!\n", get_modstr(), connection);
fprintf(logfile, "%s:%s:errno=%d\n", get_modstr(), what, errnum); if (errnum >= 0 && errnum < _sys_nerr)
if (p) { fprintf(lologfile, "%s %d:%s:%s\n", get_modstr(), connection, what, _sys_errlist[errnum]);
va_start(ap, p); else
vfprintf(logfile, p, ap); fprintf(lologfile, "%s %d:%s:errno=%d\n", get_modstr(), connection, what, errnum);
va_end(ap); if (p) {
fprintf(logfile, "\n"); va_start(ap, p);
vfprintf(lologfile, p, ap);
va_end(ap);
fprintf(lologfile, "\n");
}
fflush(lologfile);
if ((!mode) || (lologfile == stderr)) break;
else lologfile = stderr;
} }
fflush(logfile);
} }
FILE *open_nw_ini(void) FILE *open_nw_ini(void)
@ -218,7 +225,7 @@ static void sig_segv(int isig)
exit(99); exit(99);
} }
void init_tools(int module) void init_tools(int module, int conn)
{ {
char buff[300]; char buff[300];
char logfilename[300]; char logfilename[300];
@ -226,7 +233,8 @@ void init_tools(int module)
int withlog=0; int withlog=0;
int dodaemon=0; int dodaemon=0;
int new_log=0; int new_log=0;
in_module = module; in_module = module;
connection = conn;
if (f) { if (f) {
int what; int what;
while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { /* daemonize */ while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { /* daemonize */

View File

@ -1,4 +1,4 @@
/* tools.h : 10-Feb-96 */ /* tools.h : 10-Mar-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
@ -46,7 +46,7 @@ extern int get_ini_entry(FILE *f, int entry, char *str, int strsize);
extern char *get_exec_path(char *buff, char *progname); extern char *get_exec_path(char *buff, char *progname);
extern int get_ini_int(int what); extern int get_ini_int(int what);
extern void get_ini_debug(int what); extern void get_ini_debug(int what);
extern void init_tools(int module); extern void init_tools(int module, int conn);
extern uint8 down_char(uint8 ch); extern uint8 down_char(uint8 ch);
extern uint8 up_char(uint8 ch); extern uint8 up_char(uint8 ch);