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
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. :)
INSTALLATION
look in doc/INSTALL or doc/INSTALL.ger
Martin
(mstover@freeway.de)
HELP
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. :-(
To get help you can mail to and/or subscribe to LinWare mailing list:
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
*
* This program is free software; you can redistribute it and/or modify
@ -30,6 +30,9 @@ extern int errno;
static int test_handle=-1;
#endif
#define DONT_KNOW_IF_OK 1
static int default_uid=-1;
static int default_gid=-1;
@ -158,8 +161,8 @@ void set_default_guid(void)
{
seteuid(0);
if (setegid(default_gid) < 0 || seteuid(default_uid) < 0) {
fprintf(stderr, "Cannot set default gid=%d and uid=%d\nABORTET!!\n" ,
default_gid, default_uid);
errorp(1, "set_default_guid, !! Abort !!",
"Cannot set default gid=%d and uid=%d" , default_gid, default_uid);
exit(1);
}
}
@ -680,6 +683,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
return(completition);
}
static int lastdirhandle=0;
int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
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
*/
{
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);
return(completition);
}
@ -810,6 +822,13 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus)
struct stat stbuff;
int completition=-0x9c;
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);
if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */
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)
/* Cann be called when ever you want */
{
@ -971,12 +997,12 @@ int nw_init_connect(void)
fclose(f);
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);
}
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));
return(-1);
}
@ -1052,7 +1078,7 @@ int nw_search(uint8 *info,
{
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",
nwpath.path, nwpath.fn, completition));
if (completition > -1) {

View File

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

View File

@ -83,7 +83,15 @@ Erste 'oeffentliche' Version
- Passwort Strategy erweitert. Nun ist es auch moeglich ueber
entry '7' in der ini Datei System-Passwoerter zu verwenden.
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:
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
Title: mars_nwe
Version: 0.96pl9
Entered-date: 13-Feb-96
Version: 0.97
Entered-date: 10-Mar-96
Description: full novell-server-emulator (src),beta
supports file-services, bindery-services,
printing-services, routing-services
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@freeway.de (Martin Stover)
Maintained-by: mstover@freeway.de (Martin Stover)
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
Platforms: Linux (1.2.xx, 1.3.32, > 1.3.55 tested, others should work)
Copying-policy: GNU

View File

@ -36,6 +36,11 @@ typedef struct {
uint8 sock[IPX_SOCK_SIZE];
} ipxAddr_t;
#define IPXCMPSOCK(a, b) ( \
((char *)(a))[0] == ((char*)(b))[0] && \
((char *)(a))[1] == ((char*)(b))[1] \
)
#define IPXCMPNODE(a, b) ( \
((char *)(a))[0] == ((char*)(b))[0] && \
((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
the dirty dosemu-patch to the dosemu program.
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.

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 */
#define DO_DEBUG 1 /* Debugging einschalten */
#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 */
#define DO_DEBUG 1 /* Compile in debug code */
#define DO_TESTING 0
#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_APPL_NMBR 0x2222 /* Applikation Number 2 Byte */
@ -13,21 +21,21 @@
#define MAX_NW_VOLS 10 /* max. Volumes */
#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. */
/* to enable testing of them this */
/* entry must be changed to '1' and */
/* entry '6' in ini file must be set */
/* to '1', too. */
/* to > '0', too. */
#define MAX_NW_SERVERS 40 /* max. count of servers */
/* <--------------- 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_NW_ROUTES 50 /* max. networks (internal + external) */
/* 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
# last change: 13-Feb-96
# (C)opyright 1993, 1996, Martin Stover, Softwareentwicklung, Marburg
# last change: 08-Mar-96
# MAR.S NW-Server Emulator
# Einfache Konfiguration, alles ab # ist Kommentar.
# Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt.
@ -52,16 +52,16 @@
# simple namespace services are implemented for testing
# since V 0.96pl8. To test them, this entry must be set to '1'.
# 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
7 0 # 0 = use only encrypted passwords stuff (default)
# 1 = allow the unencrypted change password routine.
# 8 = allow all unencrypted stuff.
# 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
# will be used for not logins
# will be used for not logins or not assigned mars_nwe users.
10 200 # GID
11 201 # UID
#############################
@ -77,6 +77,17 @@
## NW-Name UNIX-Name [PASSWORD]
#13 MAR 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
# the queue Directory must exist before printing !!!
@ -85,7 +96,7 @@
#21 Q2 SYS:/PRINT/Q2 lpr -C printer2
#############################
# >= 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)
101 1 # debug NWSERV
102 0 # debug NCPSERV
@ -95,17 +106,24 @@
200 1 # 0 = no logfile and dont daemonize nwserv
# # 1 = daemonize nwserv and use logfile
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
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.
302 1 # creat new filename=1, append to file=0
#############################
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
#makefile.unx 10-Feb-96
#makefile.unx 08-Mar-96
#endif
VPATH=$(V_VPATH)
@ -8,9 +8,9 @@ O=.o
C=.c
V_H=0
V_L=96
P_L=9
#define D_P_L 1
V_L=97
P_L=0
#define D_P_L 0
DISTRIB=mars_nwe
#if D_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
$(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) $<
n_all: $(PROGS)
@echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes
n_install_ini:
cd $(VPATH) && $(INSTALL) -m 664 nw.ini $(M_FILENAME_NW_INI) && cd $(OBJDIR)
@ -160,7 +161,10 @@ echo ""; \
fi; cd $(OBJDIR) )
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
rm -f *.o
@ -173,23 +177,21 @@ n_make_dir: n_clean1
cd $(VPATH) && (rm -rf $(OBJDIR)/$(VPATH)/$(DISTRIB) \
; mkdir $(DISTRIB) \
; mkdir $(DISTRIB)/examples \
; mkdir $(DISTRIB)/doc \
; ln -f \
$(STERN).[ch] \
makefile.unx \
Makefile \
COPYING \
NEWS \
CHANGES \
README \
README.ger \
INSTALL \
INSTALL.ger \
$(DISTRIB).lsm \
$(DISTRIB)/. \
; rm -f $(DISTRIB)/config.h \
; ln -f \
examples/$(STERN) \
$(DISTRIB)/examples/. \
; ln -f \
doc/$(STERN) \
$(DISTRIB)/doc/. \
; cd $(OBJDIR) )
n_diff: n_make_dir
@ -202,28 +204,22 @@ n_distrib: n_diff
-mkdir /tmp/x
cd $(VPATH) && (tar cvzf $(DISTRIBF).tgz $(DISTRIB) \
; 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 \
; cat $(DISTRIBF).uue >> /tmp/yy \
; chmod 664 /tmp/yy \
; rm $(DISTRIBF).uue \
; mv $(DISTRIBF).tgz /tmp/x/. \
; cp -a $(DISTRIB)/$(DISTRIB).lsm /tmp/x/. \
; cp -a $(DISTRIB)/doc/$(DISTRIB).lsm /tmp/x/. \
; cd $(OBJDIR) )
n_distrib_bin:
cd $(VPATH) && (tar cvzf /tmp/$(DISTRIB).bin.tgz \
$(PROGS) \
COPYING \
INSTALL \
INSTALL.ger \
NEWS \
CHANGES \
README \
README.ger \
$(DISTRIB).lsm \
examples \
doc \
; cd $(OBJDIR))

550
ncpserv.c
View File

@ -1,5 +1,5 @@
/* ncpserv.c */
#define REVISION_DATE "13-Feb-96"
#define REVISION_DATE "10-Mar-96"
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -19,7 +19,11 @@
#include "net.h"
#include "nwdbm.h"
#if !CALL_NCPSERV_OVER_SOCKET
static struct pollfd polls[2];
#endif
static int ncp_fd = -1;
static uint8 ipx_in_data[IPX_MAX_DATA+500]; /* space for additional data */
static NCPREQUEST *ncprequest = (NCPREQUEST*)&ipx_in_data;
@ -32,6 +36,10 @@ static int rcv_flags = 0;
static char my_nwname[50];
static time_t akttime;
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,
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));
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));
break;
@ -85,12 +93,12 @@ static void write_to_nwserv(int what, int connection, int mode,
#define nwserv_down_server() \
write_to_nwserv(0xffff, 0, 0, NULL, 0)
static int open_ncp_socket()
static int open_ipx_sockets()
{
struct t_bind bind;
ncp_fd=t_open("/dev/ipx", O_RDWR, NULL);
if (ncp_fd < 0) {
if (nw_debug) t_error("t_open !Ok");
t_error("t_open !Ok");
return(-1);
}
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.qlen = 0; /* immer */
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);
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);
}
typedef struct {
int fd; /* writepipe */
int fd; /* writepipe */
/* or if CALL_NWCONN_OVER_SOCKET then sock_nr of nwconn */
int pid; /* pid from son */
ipxAddr_t client_adr; /* address client */
uint32 object_id; /* logged object */
@ -126,43 +149,53 @@ static int anz_connect=0; /* actual anz connections */
static int new_conn_nr(void)
{
int j = -1;
int one_found=0;
if (!anz_connect){ /* init all */
j = MAX_CONNECTIONS;
while (j--) {
connections[j].fd = -1;
connections[j].pid = -1;
connections[j].message[0] = '\0';
}
anz_connect++;
return(1);
}
j = -1;
while (++j < MAX_CONNECTIONS) {
CONNECTION *c=&(connections[j]);
if (c->fd < 0) {
if (c->fd < 0 && c->pid < 0) {
c->message[0] = '\0';
if (++j > anz_connect) anz_connect=j;
return(j);
}
}
/* nothing free */
j=MAX_CONNECTIONS;
while (j--) {
while (j-- && one_found < 3) {
CONNECTION *c=&(connections[j]);
if (!c->object_id) { /* NOT LOGGED IN */
/* makes wdog test faster */
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 */
}
static int free_conn_nr(int nr)
{
if (nr && --nr < anz_connect) {
connections[nr].fd = -1;
connections[nr].fd = -1;
connections[nr].pid = -1;
return(0);
}
return(-1);
@ -185,21 +218,43 @@ static void clear_connection(int conn)
if (conn > 0 && --conn < anz_connect) {
CONNECTION *c = &connections[conn];
if (c->fd > -1) {
#if !CALL_NWCONN_OVER_SOCKET
close(c->fd);
#endif
c->fd = -1;
if (c->pid > -1) {
kill(c->pid, SIGTERM); /* kill it */
c->pid = -1;
}
if (c->pid > -1) kill(c->pid, SIGTERM); /* kill it */
}
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--) {
CONNECTION *c = &connections[conn];
if (c->fd < 0) anz_connect--;
else break;
if (c->pid == pid) clear_connection(conn+1);
}
}
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)
@ -214,6 +269,7 @@ static int find_get_conn_nr(ipxAddr_t *addr)
if (!connection){
if ((connection = new_conn_nr()) > 0){
CONNECTION *c=&(connections[connection-1]);
#if !CALL_NWCONN_OVER_SOCKET
int fds[2];
memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t));
if (pipe(fds) < 0) {
@ -221,15 +277,50 @@ static int find_get_conn_nr(ipxAddr_t *addr)
free_conn_nr(connection);
return(0);
} 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 pid = fork();
if (pid < 0) {
errorp(0, "find_get_conn_nr, fork", NULL);
free_conn_nr(connection);
#if !CALL_NWCONN_OVER_SOCKET
close(fds[0]);
close(fds[1]);
#endif
return(0);
}
if (pid == 0) {
/* new process */
char *progname="nwconn";
@ -238,10 +329,14 @@ static int find_get_conn_nr(ipxAddr_t *addr)
char connstr[20];
char addrstr[100];
int j = 2;
#if !CALL_NWCONN_OVER_SOCKET
close(fds[1]); /* no writing */
dup2(fds[0], 0); /* becomes stdin */
close(fds[0]); /* not needed */
#else
dup2(ipx_fd, 0); /* becomes stdin */
close(ipx_fd);
#endif
while (j++ < 100) close(j); /* close all > stderr */
sprintf(pidstr, "%d", akt_pid);
@ -253,8 +348,13 @@ static int find_get_conn_nr(ipxAddr_t *addr)
exit(1); /* normaly not reached */
}
c->pid = pid;
#if CALL_NWCONN_OVER_SOCKET
c->fd = (int) GET_BE16(my_addr.sock);
close(ipx_fd);
#else
c->fd = fds[1];
close(fds[0]); /* no need to read */
#endif
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;
}
#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)
/* 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;
} else {
xdata->version = 3;
xdata->subversion = 11;
xdata->subversion = (tells_server_version == 2)
? 12
: 11;
}
i=0;
@ -888,7 +1000,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
newpassword));
if (c->object_id == 1 ||
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;
} else {
@ -1232,10 +1344,16 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
ncpresponse->completition = completition;
if (c->message[0]) connect_status |= 0x40;
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,
sizeof(NCPRESPONSE) + data_len);
#endif
XDPRINTF((2, 0, "0x%x 0x%x compl:0x%x, write to %d, anz = %d",
func, (int)ufunc, (int) completition, c->fd, data_len));
return(0); /* ok */
}
@ -1256,20 +1374,24 @@ static void ncp_response(int type, int sequence,
if (nw_debug){
char comment[80];
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,
&from_addr, comment);
} else
send_ipx_data(-1, 17, sizeof(NCPRESPONSE) + data_len,
send_ipx_data(ipx_out_fd, 17, sizeof(NCPRESPONSE) + data_len,
(char *) ncpresponse,
&from_addr, NULL);
}
#if 0
static void sig_child(int isig)
{
int k=-1;
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) {
while (++k < anz_connect) {
CONNECTION *c = &connections[k];
@ -1278,9 +1400,10 @@ static void sig_child(int isig)
break;
}
}
kill(pid, SIGKILL); /* kill it */
}
signal(SIGCHLD, sig_child);
}
#endif
static void close_all(void)
{
@ -1291,20 +1414,32 @@ static void close_all(void)
t_close(ncp_fd);
XDPRINTF((2,0, "LEAVE ncpserv"));
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)
{
close_all();
exit(0);
server_is_down++;
}
static int got_sig_child=0;
static void sig_child(int isig)
{
got_sig_child++;
signal(SIGCHLD, sig_child);
}
static void set_sig(void)
{
signal(SIGTERM, sig_quit);
signal(SIGQUIT, sig_quit);
signal(SIGTERM, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, sig_child);
@ -1323,7 +1458,7 @@ static void handle_bind_calls(uint8 *p)
p += 2;
strmaxcpy(obj.name, p+1, *p);
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,
(char *)p, sizeof(ipxAddr_t));
}
@ -1343,26 +1478,68 @@ static void handle_bind_calls(uint8 *p)
}
}
static int handle_ctrl(void)
/* reads stdin pipe */
static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size)
{
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 conn;
int result = 0;
int data_len = read(0, (char*)&what, sizeof(what));
if (data_len == sizeof(what)) {
XDPRINTF((2, 0, "GOT CTRL what=0x%x", what));
int offs=0;
int data_len = xread(&ipxd, &offs, (uint8*)&(what), sizeof(int));
if (data_len == sizeof(int)) {
XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd.owndata.d.size));
switch (what) {
case 0x5555 : /* clear_connection */
data_len = read(0, (char*)&conn, sizeof(conn));
if (sizeof(int) == data_len) clear_connection(conn);
if (sizeof (int) ==
xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int)))
clear_connection(conn);
break;
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);
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);
else
XDPRINTF((1, 1, "0x3333 protokoll error:len=%d", conn));
@ -1372,11 +1549,12 @@ static int handle_ctrl(void)
case 0xeeee:
get_ini_debug(NCPSERV);
nw_fill_standard(NULL, NULL);
(void)nw_fill_standard(NULL, NULL);
sync_dbm();
break;
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)
sent_down_message();
break;
@ -1384,27 +1562,175 @@ static int handle_ctrl(void)
default : break;
} /* switch */
result++;
} else XDPRINTF((2, 0, "GOT CTRL size=%d", data_len));
} else {
errorp(1, "handle_ctrl", "wrong data len=%d", data_len);
}
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 result;
int type;
if (argc != 3) {
fprintf(stderr, "usage ncpserv address nwname\n");
exit(1);
}
init_tools(NCPSERV);
init_tools(NCPSERV, 0);
strncpy(my_nwname, argv[1], 48);
my_nwname[47] = '\0';
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
set_emu_tli();
#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.maxlen = sizeof(ipx_pack_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;
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].revents = polls[1].revents= 0;
polls[0].fd = ncp_fd;
polls[1].fd = 0; /* stdin */
while (1) {
while (!server_is_down) {
int anz_poll = poll(polls, 2, 60000);
time(&akttime);
if (anz_poll > 0) { /* i have to work */
struct pollfd *p = &polls[0];
int j = -1;
while (++j < 2) {
if (p->revents){
if (!j) { /* ncp-socket */
XDPRINTF((99,0, "POLL revents=%d", p->revents));
if (p->revents & ~POLLIN)
errorp(0, "STREAM error", "revents=0x%x", p->revents );
else {
if ((result = t_rcvudata(ncp_fd, &ud, &rcv_flags)) > -1){
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
handle_ncp_request();
} else if (p->fd==0) { /* fd_ncpserv_in */
XDPRINTF((2,0,"POLL %d, fh=%d", p->revents, p->fd));
if (p->revents & ~POLLIN)
@ -1558,7 +1783,12 @@ int main(int argc, char *argv[])
} else {
XDPRINTF((3,0,"POLLING ..."));
}
if (got_sig_child) {
kill_connections();
got_sig_child=0;
}
}
#endif
close_all();
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
*
@ -93,8 +93,25 @@
/* ===================> 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"
#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
# define DO_DEBUG 1
#endif
@ -270,6 +287,15 @@ typedef union {
uint8 reserved; /* high connection */
uint8 function; /* Function */
} 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];
} IPX_DATA;
@ -283,6 +309,7 @@ typedef struct S_CONFREQ CONFREQ;
typedef struct S_DIAGRESP DIAGRESP;
typedef struct S_NCPRESPONSE NCPRESPONSE;
typedef struct S_NCPREQUEST NCPREQUEST;
typedef struct S_OWN_DATA OWN_DATA;
/* SOCKETS */
#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 node0, node1, node2, node3, node4, node5;
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,
&node0, &node1, &node2, &node3, &node4, &node5,
&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)
{
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[1] ,
(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)
{
init_tools(NWCLIENT);
init_tools(NWCLIENT, 0);
if (argc != 3) {
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 */
/* (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 int ncp_type;
static int open_ipx_socket()
static int open_ipx_socket(int wanted_sock)
{
struct t_bind bind;
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");
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.maxlen = sizeof(ipxAddr_t);
bind.addr.buf = (char*)&my_addr;
@ -67,9 +67,7 @@ static int open_ipx_socket()
return(0);
}
static int req_printed=0;
static int ncp_response(int sequence,
int completition, int data_len)
@ -1282,7 +1280,7 @@ extern int t_errno;
static void close_all(void)
{
nw_init_connect();
nw_exit_connect();
close(0);
if (ipx_fd > -1){
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)
{
close_all();
exit(0);
}
static int fl_get_debug=0;
static void get_new_debug(void)
{
get_ini_debug(3);
fl_get_debug=0;
XDPRINTF((2, 0, "Got Signal=%d", rsig));
fl_get_int=2;
}
static void sig_hup(int rsig)
{
signal(SIGHUP, SIG_IGN);
fl_get_debug++;
fl_get_int=1;
signal(SIGHUP, sig_hup);
}
#if 0
static void sig_child(int isig)
static void get_new_debug(void)
{
int status;
int pid=wait(&status);
if (pid > -1) kill(pid, SIGKILL); /* evtl Toechter killen */
signal(SIGCHLD, sig_child);
get_ini_debug(3);
fl_get_int=0;
}
#endif
static void set_sig(void)
{
signal(SIGTERM, sig_quit);
signal(SIGQUIT, sig_quit);
signal(SIGINT, sig_quit);
signal(SIGPIPE, sig_quit);
signal(SIGHUP, sig_hup);
signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
/* signal(SIGCHLD, sig_child); */
}
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) {
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection\n");
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection [sock]\n");
exit(1);
} else father_pid = atoi(*(argv+1));
setuid(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);
#ifdef LINUX
set_emu_tli();
#endif
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();
@ -1371,15 +1381,39 @@ int main(int argc, char **argv)
ncpresponse->reserved = (uint8) 0; /* allways 0 */
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();
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));
#endif
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) {
/* OK for direct sending */
data_len -= sizeof(NCPRESPONSE);
@ -1390,13 +1424,23 @@ int main(int argc, char **argv)
ncp_response((int)(ncprequest->sequence), (int)(ncprequest->function), data_len);
} else { /* this calls I must handle */
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();
}
} else if (data_len < 0) {
if (fl_get_debug) get_new_debug();
else break;
}
}
} /* while */
close_all();
XDPRINTF((2,0, "leave nwconn pid=%d", getpid()));
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
*
* This program is free software; you can redistribute it and/or modify
@ -36,18 +36,26 @@
# include <shadow.h>
#endif
#define DBM_REMAINS_OPEN 1
int tells_server_version=0;
int password_scheme=0;
static char *fnprop = "nwprop";
static char *fnval = "nwval";
static char *fnobj = "nwobj";
static datum key;
static datum data;
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];
sprintf(buff, "%s/%s", PATHNAME_BINDERY, s);
@ -55,15 +63,45 @@ static int dbminit(char *s)
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()
{
if (my_dbm != NULL) {
#if !DBM_REMAINS_OPEN
dbm_close(my_dbm);
#endif
my_dbm = NULL;
}
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 nextkey(key) dbm_nextkey(my_dbm)
#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",
o->name, (int)o->type, last_obj_id));
if (!dbminit(fnobj)){
if (!dbminit(FNOBJ)){
key = firstkey();
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));
if (!prop_id) {
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)) {
NETPROP *p=(NETPROP*)key.dptr;
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;
}
if (result > 0) {
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
int k;
NETVAL 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;
dbmclose();
if (result > 0) {
if (!dbminit(fnprop)){ /* now delete properties */
if (!dbminit(FNPROP)){ /* now delete properties */
int k;
NETPROP prop;
key.dptr = (char*)&prop;
@ -209,7 +247,7 @@ static int loc_delete_obj(uint32 objid)
{
int result=0;
(void)loc_delete_property(objid, (uint8*)"*", 0);
if (!dbminit(fnobj)){
if (!dbminit(FNOBJ)){
key.dptr = (char*)&objid;
key.dsize = NETOBJ_KEY_SIZE;
if (delete(key)) result = -0xff;
@ -232,7 +270,7 @@ int nw_rename_obj(NETOBJ *o, uint8 *newname)
int result = find_obj_id(o, 0);
if (!result) {
result = -0xff;
if (!dbminit(fnobj)){
if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o;
data = fetch(key);
@ -254,7 +292,7 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity)
int result = find_obj_id(o, 0);
if (!result) {
result = -0xff;
if (!dbminit(fnobj)){
if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o;
data = fetch(key);
@ -274,7 +312,7 @@ int nw_get_obj(NETOBJ *o)
{
int result = -0xfc; /* no Object */
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.dptr = (char*)o;
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 */
XDPRINTF((2,0, "find Prop id von name=0x%x:%s, lastid=%d",
obj_id, p->name, last_prop_id));
if (!dbminit(fnprop)){
if (!dbminit(FNPROP)){
int flag = (last_prop_id) ? 0 : 1;
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
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 */
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)) {
NETPROP *prop=(NETPROP*)key.dptr;
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 */
NETVAL val;
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val;
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 */
NETVAL val;
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val;
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 */
NETVAL val;
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val;
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 */
NETVAL val;
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
key.dsize = NETVAL_KEY_SIZE;
key.dptr = (char*)&val;
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)
{
int result = -0xec; /* no such Segment */
if (!dbminit(fnval)){
if (!dbminit(FNVAL)){
NETVAL val;
int flag = 1;
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 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);
if (result > -1) {
result=strlen(buff);
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 */
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)) {
data = fetch(key);
if (data.dptr){
@ -801,7 +843,7 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id)
int nw_obj_has_prop(NETOBJ *obj)
{
int result = (dbminit(fnprop)) ? -0xff : 0;
int result = (dbminit(FNPROP)) ? -0xff : 0;
if (!result){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
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 result=0;
if (!dbminit(fnprop)){
if (!dbminit(FNPROP)){
uint8 founds[256];
memset((char*)founds, 0, sizeof(founds) );
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
@ -853,7 +895,6 @@ int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop)
return(result);
}
int nw_create_prop(int object_type,
uint8 *object_name, int object_namlen,
uint8 *prop_name, int prop_namlen,
@ -876,35 +917,51 @@ int nw_create_prop(int object_type,
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 *propname, int propflags, int propsecurity,
char *value, int valuesize)
/*
* 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
*/
{
NETOBJ obj;
NETPROP prop;
if (objname && *objname){
strmaxcpy(obj.name, objname, sizeof(obj.name));
obj.type = (uint8)objtype;
obj.flags = (uint8)objflags;
obj.security = (uint8)objsecurity;
obj.id = 0; /* Erstmal */
nw_create_obj(&obj, wanted_id);
} else obj.id = wanted_id;
strmaxcpy(prop.name, propname, sizeof(prop.name));
prop.flags = (uint8)propflags;
prop.security = (uint8)propsecurity;
nw_create_obj_prop(&obj, &prop);
if (valuesize){
uint8 locvalue[128];
memset(locvalue, 0, sizeof(locvalue));
memcpy(locvalue, value, min(sizeof(locvalue), valuesize));
ins_prop_val(obj.id, prop.id, 1, locvalue, 0xff);
if (objname && *objname)
nw_new_obj(&wanted_id, objname, objtype,
objflags, objsecurity);
obj.id = wanted_id;
if (propname && *propname) {
strmaxcpy(prop.name, propname, sizeof(prop.name));
prop.flags = (uint8)propflags;
prop.security = (uint8)propsecurity;
nw_create_obj_prop(&obj, &prop);
if (valuesize){
uint8 locvalue[128];
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);
}
@ -1012,19 +1069,20 @@ int nw_test_unenpasswd(uint32 obj_id, uint8 *password)
} 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";
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,
passwd, 16);
} else
} else if (!dont_ch)
(void)loc_delete_property(obj_id, prop_name, 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) {
uint8 passwd[200];
@ -1051,9 +1109,9 @@ int nw_set_passwd(uint32 obj_id, char *password)
(int)passwd[14],
(int)passwd[15]));
#endif
return(nw_set_enpasswd(obj_id, passwd));
return(nw_set_enpasswd(obj_id, passwd, dont_ch));
} 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));
U32_TO_BE32(su_id, buff);
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,
(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, strlen(q_directory));
/* 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_command, strlen(q_command));
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,
(char*)buff, 4);
#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,
NULL, 0);
#endif
}
static void add_user(uint32 u_id, uint32 g_id,
char *name, char *unname, char *password)
static void add_user_to_group(uint32 u_id, uint32 g_id)
{
uint8 buff[4];
U32_TO_BE32(g_id, buff);
u_id = /* Typ Flags Security */
nw_new_create_prop(u_id, name, 0x1 , 0x0, 0x33,
"GROUPS_I'M_IN", P_FL_SET, 0x31,
/* Typ Flags Security */
nw_new_obj_prop(u_id, NULL, 0x1 , 0x0, 0x33,
"GROUPS_I'M_IN", P_FL_SET, 0x31,
(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_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)
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,
(char*)unname, strlen(unname));
if (password && *password) {
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 */
{
char serverna[MAX_SERVER_NAME+2];
@ -1176,16 +1309,22 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
uint32 ngr_id = 0x0C000001;
uint32 ps1_id = 0x0D000001;
#endif
FILE *f = open_nw_ini();
ge_id =
nw_new_create_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31,
"GROUP_MEMBERS", P_FL_SET, 0x31,
NULL, 0);
FILE *f = open_nw_ini();
int auto_ins_user = 0;
char auto_ins_passwd[100];
int make_tests = 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){
char buff[500];
char buff[256];
int what;
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);
} else if (7 == what) { /* password_scheme */
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);
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 uname[100];
char password[100];
@ -1241,9 +1381,19 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
upstr(nname);
if (anz > 2) upstr(password);
else password[0] = '\0';
add_user((12 == what) ? su_id : 0L, ge_id, nname,
uname, password);
if (what == 14)
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 */
fclose(f);
@ -1251,13 +1401,73 @@ void nw_fill_standard(char *servername, ipxAddr_t *adr)
if (servername && adr) {
strmaxcpy(serverna, servername, MAX_SERVER_NAME);
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,
(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
* 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 */
uint8 props[10000]; /* max 10000 Properties */
create_nw_db(fnobj, 0);
create_nw_db(fnprop, 0);
create_nw_db(fnval, 0);
create_nw_db(dbm_fn[FNOBJ], 0);
create_nw_db(dbm_fn[FNPROP], 0);
create_nw_db(dbm_fn[FNVAL], 0);
if (!dbminit(fnobj)){
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->flags & O_FL_DYNA) /* Dynamisch */
if ((obj->flags & O_FL_DYNA) || !obj->name[0]) {
/* dynamic or without name */
objs[anz++] = obj->id;
if (anz == 10000) break;
}
}
}
}
dbmclose();
while (anz--) loc_delete_obj(objs[anz]); /* Now delete */
anz = 0;
if (!dbminit(fnprop)){
if (!dbminit(FNPROP)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key);
if (data.dptr) {
@ -1294,13 +1507,16 @@ void nw_init_dbm(char *servername, ipxAddr_t *adr)
if (prop->flags & P_FL_DYNA) { /* Dynamisch */
objs[anz] = prop->obj_id;
props[anz++] = prop->id;
if (anz == 10000) break;
}
}
}
}
dbmclose();
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 < ============== */

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
*
* 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_GET_KEY_FAIL 4
extern void sync_dbm(void);
extern int nw_get_prop(int object_type,
uint8 *object_name, int object_namlen,
@ -171,7 +172,7 @@ extern int nw_create_prop(int object_type,
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 *propname, int propflags, int propsecurity,
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_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_prcommand(uint32 q_id, uint8 *buff);
extern void nw_fill_standard(char *servername, ipxAddr_t *adr);
extern void nw_init_dbm(char *servername, ipxAddr_t *adr);
extern int nw_fill_standard(char *servername, ipxAddr_t *adr);
extern int nw_init_dbm(char *servername, ipxAddr_t *adr);
#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
*
* 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;
} else if (do_delete) {
nr=nw_servers[k];
#if !FILE_SERVER_INACTIV
if (!IPXCMPNODE(nr->addr.node, my_server_adr.node) ||
!IPXCMPNET (nr->addr.net, my_server_adr.net) )
#endif
{
ins_del_bind_net_addr(nr->name, nr->typ, NULL);
xfree(nr->name);
@ -394,7 +396,7 @@ void send_server_response(int respond_typ,
/* respond_typ 2 = general, 4 = nearest service respond */
{
IPX_DATA ipx_data;
int j=-1;
int j=-1;
int tics=99;
int hops=15;
int entry = -1;
@ -450,8 +452,14 @@ static void send_sap_broadcast(int mode)
U16_TO_BE16(SOCK_SAP, wild.sock);
while (++j < anz_servers) {
NW_SERVERS *nw=nw_servers[j];
if (!nw->typ || (nw->net == nd->net && nw->hops)
|| (mode == 2 && nw->hops) ) continue; /* no SAP to this NET */
if ( !nw->typ /* server has no typ */
|| ( 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));
strcpy(ipx_data.sip.server_name, nw->name);
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=2, shutdown */
{
static int flipflop=0;
static int flipflop=1;
if (mode) {
send_sap_broadcast(mode);
send_rip_broadcast(mode);
send_sap_broadcast(mode);
} else {
if (flipflop) {
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
*
* 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 */
#endif
static ipxAddr_t nw386_adr; /* Address of NW-TEST Server */
static int nw386_found = 0;
static int client_mode = 0;
static int nw386_found = 0;
static int client_mode = 0;
static int ipxdebug = 0;
static int pid_ncpserv = -1;
#if !CALL_NCPSERV_OVER_SOCKET
static int fd_ncpserv_out = -1; /* ctrl-pipe out to ncpserv */
#endif
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
static time_t akttime_stamp = 0;
static int broadsecs = 2048;
static int broadmillisecs = 2000; /* 2 sec */
static time_t server_down_stamp = 0;
static int server_goes_down_secs = 10;
static int server_broadcast_secs = 60;
static int save_ipx_routes = 0;
static uint8 *station_fn=NULL;
static int nearest_request_flag=0;
#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,
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",
what, connection, data_size));
switch (what) {
case 0x5555 : /* kill connection */
write(fd_ncpserv_out, (char*) &what, sizeof(int));
write(fd_ncpserv_out, (char*) &connection, sizeof(int));
add_wdata(&ipxd, (char*) &connection, sizeof(int));
break;
case 0x3333 : /* 'bindery' calls */
write(fd_ncpserv_out, (char*) &what, sizeof(int));
write(fd_ncpserv_out, (char*) &data_size, sizeof(int));
write(fd_ncpserv_out, data, data_size);
add_wdata(&ipxd, (char*)&data_size, sizeof(int));
add_wdata(&ipxd, data, data_size);
break;
case 0xeeee : /* hup, read init */
write(fd_ncpserv_out, (char*) &what, sizeof(int));
break;
case 0xffff : /* 'down server' */
write(fd_ncpserv_out, (char*) &what, sizeof(int));
write(fd_ncpserv_out, (char*) &what, sizeof(int));
add_wdata(&ipxd, (char*) &what, sizeof(int));
break;
default : break;
default : return;
}
write_wdata(&ipxd, what);
}
#else
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)
{
#if !FILE_SERVER_INACTIV
#if !CALL_NCPSERV_OVER_SOCKET
int fds_out[2];
#endif
int fds_in[2];
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()) {
case 0 : { /* new Process */
@ -192,10 +228,11 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
char addrstr[100];
char pathname[300];
int j = FD_NWSERV;
#if !CALL_NCPSERV_OVER_SOCKET
close(fds_out[1]); /* no need to write */
dup2(fds_out[0], 0); /* becommes stdin */
close(fds_out[0]); /* no longer needed */
#endif
close(fds_in[0]); /* no need to read */
dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */
close(fds_in[1]); /* no longer needed */
@ -207,14 +244,19 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
}
break;
case -1: close(fds_out[0]);
case -1:
#if !CALL_NCPSERV_OVER_SOCKET
close(fds_out[0]);
close(fds_out[1]);
#endif
close(fds_in[0]);
close(fds_in[1]);
return(-1); /* error */
}
#if !CALL_NCPSERV_OVER_SOCKET
fds_out[0] = -1;
fd_ncpserv_out = fds_out[1];
#endif
fds_in[1] = -1;
fd_ncpserv_in = fds_in[0];
pid_ncpserv = pid;
@ -243,8 +285,11 @@ static int start_nwclient(void)
}
/* =========================== WDOG =============================== */
#ifndef _WDOG_TESTING_
#define _WDOG_TESTING_ 0
#endif
#ifdef _WDOG_TESTING_
#if _WDOG_TESTING_
/* for testing */
# define WDOG_TRIE_AFTER_SEC 1
# define MAX_WDOG_TRIES 1
@ -314,15 +359,13 @@ static void modify_wdog_conn(int conn, int mode)
if (mode < 99) {
c->last_time = akttime_stamp;
switch (mode) {
case 1 : c->counter = MAX_WDOG_TRIES; /* quick test */
broadsecs = 4096;
case 1 : c->counter = MAX_WDOG_TRIES; /* quick test */
break;
case 2 : c->counter = 1; /* slow test (activate)*/
broadsecs = 4096;
case 2 : c->counter = max(2, MAX_WDOG_TRIES); /* slow test (activate)*/
break;
default : c->counter = 0; /* reset */
default : c->counter = 0; /* reset */
break;
} /* switch */
} 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;
while (k--) {
CONN *c = &(conns[k]);
if (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) {
/* now its enough with trying */
/* 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)));
}
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,
int ipx_pack_typ,
int data_len,
@ -402,7 +501,19 @@ static void handle_sap(int fd,
XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d von %s",
server_type, visable_ipx_adr(from_addr)));
/* 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 */
XDPRINTF((2,0, "SAP GENERAL request server_type =%d", server_type));
send_server_response(2, server_type, from_addr);
@ -755,6 +866,12 @@ static void get_ini(int full)
server_goes_down_secs = 10;
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);
break;
@ -767,6 +884,12 @@ static void get_ini(int full)
case 310 : wdogs_till_tics=atoi(inhalt);
break;
case 400 : new_str(station_fn, (uint8*)inhalt);
break;
case 401 : nearest_request_flag=atoi(inhalt);
break;
default : break;
} /* switch */
} /* if */
@ -777,6 +900,11 @@ static void get_ini(int full)
if (print_route_tac && !pr_route_info_fn && !*pr_route_info_fn)
print_route_tac = 0;
if (!print_route_tac) xfree(pr_route_info_fn);
#if INTERNAL_RIP_SAP
server_broadcast_secs /= 2;
#endif
if (full) {
#ifdef LINUX
# if INTERNAL_RIP_SAP
@ -828,15 +956,17 @@ static void close_all(void)
if (pid_ncpserv > 0) {
int status;
#if !CALL_NCPSERV_OVER_SOCKET
if (fd_ncpserv_out > -1) {
close(fd_ncpserv_out);
fd_ncpserv_out =-1;
}
#endif
if (fd_ncpserv_in > -1) {
close(fd_ncpserv_in);
fd_ncpserv_in = -1;
}
kill(pid_ncpserv, SIGTERM); /* terminate ncpserv */
kill(pid_ncpserv, SIGQUIT); /* terminate ncpserv */
waitpid(pid_ncpserv, &status, 0);
kill(pid_ncpserv, SIGKILL); /* kill ncpserv */
}
@ -869,7 +999,7 @@ static void down_server(void)
fprintf(stderr, "\n*********************************************\n");
sleep(1);
fprintf(stderr, "\007\n");
broadsecs=100;
broadmillisecs = 100;
server_down_stamp = akttime_stamp;
send_down_broadcast();
}
@ -908,6 +1038,8 @@ static void set_sigs(void)
signal(SIGHUP, sig_hup);
}
static int server_is_down=0;
int main(int argc, char **argv)
{
int j = -1;
@ -915,7 +1047,7 @@ int main(int argc, char **argv)
if (argc > 1) client_mode=1;
/* in client mode the testprog 'nwclient' will be startet. */
init_tools(NWSERV);
init_tools(NWSERV, 0);
get_ini(1);
while (++j < NEEDED_POLLS) {
@ -955,12 +1087,12 @@ int main(int argc, char **argv)
&my_server_adr, &server_adr_sap, 0, 0, 0);
}
#endif
while (1) {
int anz_poll = poll(polls, NEEDED_POLLS, broadsecs);
while (!server_is_down) {
int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs);
int call_wdog=0;
time(&akttime_stamp);
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();
}
if (anz_poll > 0) { /* i have to work */
@ -1006,6 +1138,7 @@ int main(int argc, char **argv)
&& sizeof(int) == read(fd_ncpserv_in,
(char*)&what, sizeof(what)))
modify_wdog_conn(conn, what);
if (what > 0 && what < 99) call_wdog++;
break;
case 0x6666 : /* bcast message */
@ -1035,25 +1168,29 @@ int main(int argc, char **argv)
} else {
XDPRINTF((99,0,"POLLING ..."));
}
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 {
if (akttime_stamp - broadtime > (broadsecs / 1000)) { /* ca. 30 seconds */
send_sap_rip_broadcast((broadsecs<3000) ? 1 :0); /* firsttime broadcast */
if (broadsecs < 30000) {
int bsecs = broadmillisecs / 1000;
int difftime = akttime_stamp - broadtime;
if (difftime > bsecs) {
send_sap_rip_broadcast((bsecs < 3) ? 1 : 0); /* firsttime broadcast */
if (bsecs < server_broadcast_secs) {
rip_for_net(MAX_U32);
get_servers();
broadsecs *= 2;
if (broadsecs > 30000)
#if INTERNAL_RIP_SAP
broadsecs = 30000; /* every 30 sec. */
#else
broadsecs = 60000; /* every 60 sec. */
#endif
bsecs *= 2;
if (bsecs > server_broadcast_secs)
bsecs=server_broadcast_secs;
broadmillisecs = bsecs*1000+10;
}
send_wdogs();
send_wdogs(call_wdog);
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 */
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
*
* This program is free software; you can redistribute it and/or modify
@ -29,7 +29,8 @@ extern char _sys_errlist[];
int nw_debug=0;
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[] =
{ "???????",
"NWSERV ",
@ -46,7 +47,7 @@ char *xmalloc(uint size)
{
char *p = (size) ? (char *)malloc(size) : (char*)NULL;
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);
}
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;
if (slen) memcpy(dest, source, slen);
@ -103,7 +104,7 @@ void xdprintf(int dlevel, int mode, char *p, ...)
{
va_list ap;
if (nw_debug >= dlevel) {
if (!(mode & 1)) fprintf(logfile, "%s:", get_modstr());
if (!(mode & 1)) fprintf(logfile, "%s %d:", get_modstr(), connection);
if (p) {
va_start(ap, p);
vfprintf(logfile, p, ap);
@ -117,18 +118,24 @@ void xdprintf(int dlevel, int mode, char *p, ...)
void errorp(int mode, char *what, char *p, ...)
{
va_list ap;
int errnum = errno;
if (errnum >= 0 && errnum < _sys_nerr)
fprintf(logfile, "%s:%s:%s\n", get_modstr(), what, _sys_errlist[errnum]);
else
fprintf(logfile, "%s:%s:errno=%d\n", get_modstr(), what, errnum);
if (p) {
va_start(ap, p);
vfprintf(logfile, p, ap);
va_end(ap);
fprintf(logfile, "\n");
int errnum = errno;
FILE *lologfile = logfile;
while (1) {
if (mode) fprintf(lologfile, "\n!! %s %d:PANIC !!\n", get_modstr(), connection);
if (errnum >= 0 && errnum < _sys_nerr)
fprintf(lologfile, "%s %d:%s:%s\n", get_modstr(), connection, what, _sys_errlist[errnum]);
else
fprintf(lologfile, "%s %d:%s:errno=%d\n", get_modstr(), connection, what, errnum);
if (p) {
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)
@ -218,7 +225,7 @@ static void sig_segv(int isig)
exit(99);
}
void init_tools(int module)
void init_tools(int module, int conn)
{
char buff[300];
char logfilename[300];
@ -226,7 +233,8 @@ void init_tools(int module)
int withlog=0;
int dodaemon=0;
int new_log=0;
in_module = module;
in_module = module;
connection = conn;
if (f) {
int what;
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
*
@ -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 int get_ini_int(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 up_char(uint8 ch);