mars_nwe-0.96.pl00
This commit is contained in:
parent
5b89fe9f28
commit
cfe799f9df
42
CHANGES
Normal file
42
CHANGES
Normal file
@ -0,0 +1,42 @@
|
||||
Sorry, this is in German only. :-(
|
||||
Aenderungen in mars_nwe bis zum : 20-Dec-95
|
||||
--------------------------------
|
||||
Erste 'oeffentliche' Version
|
||||
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
|
||||
???????????????????????????????
|
||||
^^^^^^^^^^ VERSION 0.95 ^^^^^^^^
|
||||
- Login's mit Passworteingabe moeglich.
|
||||
- Benutzer mit verschiedenen Rechten moeglich,
|
||||
Mapping NW-User -> Linux-User eingebaut.
|
||||
- nwserv kann zum Daemon werden und logfile wird erzeugt.
|
||||
- Schalter fuer 'save ipx-routes after server is down' eingebaut.
|
||||
- Server kann mittels fconsole 'Server-Down' gekillt werden.
|
||||
---
|
||||
- Routing Code komplett umgeschrieben. Leider funktioniert
|
||||
das Einrichten einer internen NETWERK-Number, ala NW 311,
|
||||
und Einrichten mehrerer IPX-Devices erst nach Patchen des
|
||||
IPX-Kernel Codes. Wenn der IPX-Kernel Code fuer 1.3.[456]x
|
||||
wieder ok ist, werde ich das Anpassen bzw. werde ich es mit
|
||||
dem lwared Kernel Code versuchen.
|
||||
Falls aber nur ein ipx-interface gebraucht wird, muesste
|
||||
das IPX-Routing auch ohne IPX-Kernel Patches nun einwandfrei
|
||||
funktionieren.
|
||||
---
|
||||
- Der Server meldet nun allen Workstations, dass er down geht.
|
||||
Das funktioniert, wenn entweder der *nicht* daemonisierte
|
||||
nwserv mit ^C abgebrochen wird oder aber der daemonisierte
|
||||
nwserv ein SIGINT, SIGQUIT od. SIGTERM Signal erhaelt.
|
||||
|
||||
- Direktory Scan Fehler korrigiert.
|
||||
|
||||
- Ein HUP signal an nwserv bewirkt, dass sowohl nwserv als
|
||||
auch ncpserv die waerend der Laufzeit sinnvoll veraenderbaren
|
||||
nw.ini Parameter neu einliest. z.B. :
|
||||
- Debug Level's
|
||||
- Print Queues
|
||||
- User, User passwords
|
||||
|
||||
- Server kann sich als 2.15 Server melden oder als 3.11 .
|
||||
- Drucken mit OLD Job's (pre 3.11) Struktur eingebaut.
|
||||
^^^^^^^^^^ VERSION 0.96 ^^^^^^^^
|
||||
|
49
INSTALL
49
INSTALL
@ -1,41 +1,34 @@
|
||||
************** GERMAN ********************
|
||||
=========> Programme erzeugen <===================
|
||||
1. make aufrufen.
|
||||
2. mk.li und config.h evtl. anpassen
|
||||
3. make aufrufen.
|
||||
=========> Konfigurieren <===================
|
||||
nw.ini bearbeiten !
|
||||
=========> Installieren <===================
|
||||
"make install"
|
||||
evtl. "make install_ini" um eine installierte ini Datei
|
||||
zu *ueberschreiben* .
|
||||
=========> Starten <===================
|
||||
nwserv starten ( als root !! )
|
||||
mit Linux Version 1.2.13 getestet.
|
||||
Der Linux Kernel muss mit IPX Unterstuetzung erzeugt worden sein.
|
||||
IPX-Interface bzw. Routen werden durch das Programm automatisch
|
||||
angelegt, falls in der nw.ini Datei eine
|
||||
Networknummer > 0 angegeben wurde.
|
||||
|
||||
************** ENGLISH *******************
|
||||
=========> create programs <===================
|
||||
=========> create programs
|
||||
1. call make.
|
||||
2. perhaps you must modify mk.li and config.h
|
||||
3. call make
|
||||
=========> configure <===================
|
||||
|
||||
=========> configure
|
||||
modify nw.ini !
|
||||
=========> install <===================
|
||||
IMPORTANT !!
|
||||
Please read examples/nw.ini if you use a new version
|
||||
of mars_nwe and make the needed changes to your
|
||||
'ini' or 'conf' file.
|
||||
=========> install
|
||||
"make install"
|
||||
"make install_ini" to overwrite your old _installed_ ini.
|
||||
=========> start programs <===================
|
||||
call nwserv ( as root !! )
|
||||
|
||||
tested with Linux Version 1.2.13.
|
||||
=========> start programs
|
||||
call nwserv ( as root !! )
|
||||
tested with Linux Version 1.2.13 and 1.3.32
|
||||
the linux-kernel must be configured with IPX=Y.
|
||||
ipx-interface and ipx-routes are setup by the program if the
|
||||
network number in nw.ini is set > 0.
|
||||
entry 4 (devices) in the nw.ini file is filled.
|
||||
|
||||
=========> stop programs (server down)
|
||||
If nwserv isn't daemonized, then the server can be stopped
|
||||
with ^C, otherwise the server must be shut down with a
|
||||
kill of nwserv or with the right dos client programm
|
||||
(fconsole server down) as supervisor. Entry 210 in the
|
||||
nw.ini file gives the time in seconds, before the server
|
||||
really shuts down.
|
||||
|
||||
Viel Erfolg / good Luck :-)
|
||||
|
||||
Martin
|
||||
|
||||
(mstover@freeway.de)
|
||||
|
30
INSTALL.ger
Normal file
30
INSTALL.ger
Normal file
@ -0,0 +1,30 @@
|
||||
=========> Programme erzeugen
|
||||
1. make aufrufen.
|
||||
2. mk.li und config.h evtl. anpassen
|
||||
3. make aufrufen.
|
||||
|
||||
=========> Konfigurieren
|
||||
nw.ini bearbeiten !
|
||||
WICHTIG !!
|
||||
Bei jeder neuen Version bitte 'examples/nw.ini' kontrollieren
|
||||
und Aenderungen gegebenfalls in die eigene 'ini' bzw. 'conf'
|
||||
Datei eintragen.
|
||||
=========> Installieren
|
||||
"make install"
|
||||
evtl. "make install_ini" um eine bereits installierte ini Datei
|
||||
zu *ueberschreiben* .
|
||||
|
||||
=========> Starten
|
||||
nwserv starten ( als root !! )
|
||||
mit Linux Version 1.2.13 und 1.3.32 getestet.
|
||||
Der Linux Kernel muss mit IPX Unterstuetzung erzeugt worden sein.
|
||||
IPX-Interface bzw. Routen werden durch das Programm automatisch
|
||||
angelegt, falls in der nw.ini Datei Devices (Eintrag 4) enthalten
|
||||
sind.
|
||||
|
||||
=========> Stoppen (server down)
|
||||
Falls nwserv nicht daemonisiert wurde, kann der Server mit ^C
|
||||
wieder gestoppt werden, ansonsten muss nwserv per Dos Client
|
||||
(fconsole server down) gestoppt werden (Supervisor) oder per
|
||||
'kill' Befehl. Je nach Eintrag 210 in der nw.ini Datei kann
|
||||
das einige Sekunden dauern.
|
7
Makefile
7
Makefile
@ -1,4 +1,4 @@
|
||||
# Makefile mars_nwe: 16-Nov-95
|
||||
# Makefile mars_nwe: 06-Dec-95
|
||||
VPATH=
|
||||
all: rmeflag mk.li config.h nw.ini
|
||||
@if [ -r .eflag ] ; then \
|
||||
@ -64,8 +64,9 @@ rmeflag:
|
||||
@ - rm -f .eflag
|
||||
|
||||
nw.ini: examples/nw.ini
|
||||
@if [ -r $@ ] ; then echo "note:examples/$@ is newer then $@" > .mk.notes ; \
|
||||
echo "$@ will be touched now" >> .mk.notes; touch -c $@ ; \
|
||||
@if [ -r $@ ] ; then echo "NOTE:examples/$@ is newer then $@" > .mk.notes ; \
|
||||
echo "please compare examples/$@ with $@" >> .mk.notes; \
|
||||
echo "make the changes you need and touch $@" >> .mk.notes; \
|
||||
else cp -a examples/$@ . ; \
|
||||
echo "$@ created (from examples/$@) Please edit $@" > .mk.notes;\
|
||||
echo "and change it to your requirements." >> .mk.notes ; fi
|
||||
|
20
README
20
README
@ -18,7 +18,8 @@ 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.
|
||||
USER is SUPERVISOR with no password.
|
||||
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
|
||||
@ -46,29 +47,20 @@ short description of the processes.
|
||||
|
||||
Problems and TODO:
|
||||
Many:-(
|
||||
|
||||
Here is a short list.
|
||||
|
||||
o - Some Problems with the IPX-kernelcode.
|
||||
Frame Ethernet_ii isn't ok since linux-kernel > 1.1.??.
|
||||
with linux-kernel 1.1.44 is was still ok.
|
||||
trouble with some linux-kernel 1.3.xx
|
||||
|
||||
o - password changings from clients
|
||||
o - make routing better.
|
||||
|
||||
o - making printing better.
|
||||
|
||||
o - login's with password's.
|
||||
|
||||
o - clean the code !!!
|
||||
|
||||
o - make bindery code more complete.
|
||||
|
||||
o - and much more ...
|
||||
|
||||
Have luck with tryimg. :)
|
||||
|
||||
|
||||
Martin
|
||||
(mstover@kool.f.eunet.de)
|
||||
(mstover@freeway.de)
|
||||
|
||||
BTW: The kick to make mars_nwe public was the
|
||||
publication of linware ( lwared ), the Novell-Server-Emulator
|
||||
|
28
README.ger
28
README.ger
@ -13,9 +13,7 @@ nicht zur Verfuegung, so da
|
||||
auf Vermutungen bzw. Ausprobieren basieren. :-(
|
||||
|
||||
WARNUNG: Es gibt noch viele Bugs !!
|
||||
|
||||
z.Z. forked nwserv nicht automatisch. Er kann jederzeit
|
||||
abgebrochen und neu gestartet werden.
|
||||
Es werden aber immer weniger. :)
|
||||
|
||||
Kernel muss mit IPX Unterstuetzung erzeugt worden sein.
|
||||
IPX-Routen werden automatisch angelegt.
|
||||
@ -24,8 +22,8 @@ Anmerkungen:
|
||||
BINDERY: besteht aus den *.pag und *.dir Dateien.
|
||||
diese Dateien werden, falls nicht vorhanden,
|
||||
erzeugt und mit den Grundobjekten und Grundproperties
|
||||
gefuellt. Ein automatisch angelegter USER
|
||||
ist SUPERVISOR ohne Passwort.
|
||||
gefuellt. Der Supervisor muá in der nw.ini Datei
|
||||
bestimmt werden (Eintrag 12).
|
||||
|
||||
NETWORK: Falls auch ein Novellserver am gleichem
|
||||
Strang haengt, sollte die NETWORK Nummer
|
||||
@ -53,38 +51,26 @@ Beschreibung der Prozesse
|
||||
nwserv ueber eine PIPE verbunden, erzeugt
|
||||
einen Client-Schreib Socket.
|
||||
|
||||
|
||||
PROBLEME bzw. TODO's:
|
||||
Vieles :-(
|
||||
Hier nur eine *kleine* Auswahl.
|
||||
|
||||
o - Frame Ethernet_ii geht nicht (mehr)
|
||||
Liegt wohl am Kernel-ipx-Code. ??
|
||||
mit Kernel-Version 1.1.44 funktionierte es noch.
|
||||
einige Kernel 1.3.xx funktionieren nicht.
|
||||
|
||||
o - Passwortaenderungen durch Client ermoeglichen.
|
||||
o - Routing verbessern.
|
||||
|
||||
o - Drucken verbessern.
|
||||
|
||||
o - Login nur mit unencrypted Passwords.
|
||||
Ich kenne den Crypt-Algorithmus nicht. :-(
|
||||
Habe ihn aber jetzt bei lwared (linware) gesehen :-)
|
||||
|
||||
o - Saeubern !!
|
||||
|
||||
o - Bindery Code vervollstaendigen.
|
||||
|
||||
o - und und ...
|
||||
|
||||
Viel Spaá beim Ausprobieren. :)
|
||||
|
||||
Viel Spass beim Ausprobieren. :)
|
||||
|
||||
Ueber Erweiterungen, Korrekturen und insbesonderes der Beschreibung
|
||||
der fehlenden bzw. fehlerhaften NCP-Calls wuerde ich mich freuen.
|
||||
|
||||
|
||||
Martin
|
||||
(mstover@kool.f.eunet.de)
|
||||
(mstover@freeway.de)
|
||||
|
||||
PS: Den Anstoss, mars_nwe zu veroeffentlichen, gab die
|
||||
Veroeffentlichung von linware ( lwared ), dem Novell-Server-Emulator
|
||||
|
11
config.h
11
config.h
@ -1,11 +0,0 @@
|
||||
/* config.h: 18-Nov-95 */
|
||||
/* this config is needed by make and by cc */
|
||||
#define FILENAME_NW_INI "./nw.ini" /* location of ini (conf) file */
|
||||
#define PATHNAME_PROGS "." /* path location of progs */
|
||||
|
||||
#define MAX_CONNECTIONS 5 /* max. Number of Connections */
|
||||
#define MAX_NW_VOLS 10 /* max. Volumes */
|
||||
|
||||
#define PATHNAME_BINDERY "/tmp" /* path location of bindery */
|
||||
|
||||
#define _WDOG_TESTING_
|
379
emutli.c
379
emutli.c
@ -1,5 +1,4 @@
|
||||
/* emutli.c 17-Nov-95 */
|
||||
|
||||
/* emutli.c 18-Dec-95 */
|
||||
/*
|
||||
* One short try to emulate TLI with SOCKETS.
|
||||
*/
|
||||
@ -24,7 +23,7 @@
|
||||
/*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Some of the Code in this module is stolen from the following
|
||||
* Programms: ipx_interface, ipx_route, ipx_configure, which was
|
||||
* Programms: ipx_interface, ipx_route, ipx_configure, which were
|
||||
* written by Greg Page, Caldera, Inc.
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
@ -58,7 +57,7 @@ static int have_ipx_started=0;
|
||||
static void set_sock_debug(int sock)
|
||||
{
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &locipxdebug, sizeof(int))==-1){
|
||||
perror("setsockopt SO_DEBUG");
|
||||
errorp(0, "setsockopt SO_DEBUG", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,194 +73,167 @@ static void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i)
|
||||
memcpy(&so->sipx_port, i->sock, 2);
|
||||
}
|
||||
|
||||
void set_emu_tli(int ipx_debug)
|
||||
void set_emu_tli()
|
||||
{
|
||||
locipxdebug = ipx_debug;
|
||||
int i = get_ini_int(100);
|
||||
if (i > -1) locipxdebug = i;
|
||||
}
|
||||
|
||||
int init_ipx(char *device,
|
||||
uint32 *network,
|
||||
uint32 intnet,
|
||||
int frame,
|
||||
char *frame_name,
|
||||
int ipx_debug)
|
||||
static int x_ioctl(int sock, int mode, void *id)
|
||||
{
|
||||
int sock=-1;
|
||||
int result=-1;
|
||||
|
||||
#ifndef OLD_KERNEL_IPX
|
||||
struct ifreq id;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int i;
|
||||
memset(&id, 0, sizeof(struct ifreq));
|
||||
strcpy(id.ifr_name, device);
|
||||
locipxdebug = ipx_debug;
|
||||
|
||||
sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (socket < 0) {
|
||||
perror("EMUTLI:init_ipx");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* NUN DEBUG ein bzw. ausschalten */
|
||||
set_sock_debug(sock);
|
||||
|
||||
/* remove old ipx_interface */
|
||||
if (*network) {
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
(void) ioctl(sock, SIOCSIFADDR, &id);
|
||||
|
||||
sipx->sipx_special = IPX_PRIMARY;
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_type = frame;
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
(void) ioctl(sock, SIOCSIFADDR, &id);
|
||||
have_ipx_started++;
|
||||
}
|
||||
|
||||
sipx->sipx_special = IPX_PRIMARY; /* IPX_SPECIAL_NONE */
|
||||
/* IPX_INTERNAL */
|
||||
/* IPX_PRIMARY */
|
||||
|
||||
sipx->sipx_network = htonl(*network);
|
||||
sipx->sipx_type = frame;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_CRTITF; /* anlegen */
|
||||
/* IPX_DLTITF ist loeschen */
|
||||
|
||||
i = 0;
|
||||
int result;
|
||||
int i = 0;
|
||||
do {
|
||||
result = ioctl(sock, SIOCSIFADDR, &id);
|
||||
} while ((++i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result) {
|
||||
switch (errno) {
|
||||
case EEXIST:
|
||||
DPRINTF(("Primary network already selected.\n"));
|
||||
result = 0; /* not a reallly error */
|
||||
break;
|
||||
|
||||
case EADDRINUSE:
|
||||
fprintf(stderr, "Network number (0X%08lX) already in use.\n",
|
||||
htonl(sipx->sipx_network));
|
||||
break;
|
||||
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "Invalid frame type (%s).\n",
|
||||
frame_name);
|
||||
break;
|
||||
|
||||
case ENODEV:
|
||||
fprintf(stderr, "No such device (%s).\n",
|
||||
id.ifr_name);
|
||||
break;
|
||||
|
||||
case ENETDOWN:
|
||||
fprintf(stderr, "Requested device (%s) is down.\n",
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "Invalid device (%s).\n",
|
||||
id.ifr_name);
|
||||
break;
|
||||
|
||||
case EAGAIN:
|
||||
fprintf(stderr, "Insufficient memory to create interface.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("ioctl:SIOCSIFADDR");
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
#else /* alte Kernel Version vor ???? */
|
||||
struct ipx_route_def rt;
|
||||
locipxdebug = ipx_debug;
|
||||
rt.ipx_network=htonl(*network);
|
||||
rt.ipx_router_network=IPX_ROUTE_NO_ROUTER;
|
||||
strncpy(rt.ipx_device,"eth0",16);
|
||||
rt.ipx_flags=frame;
|
||||
sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
|
||||
if(sock==-1) {
|
||||
perror("EMUTLI:init_ipx");
|
||||
exit(1);
|
||||
}
|
||||
set_sock_debug(sock);
|
||||
result = ioctl(sock,SIOCADDRT,(void *)&rt);
|
||||
if (result && errno == EEXIST) result =0;
|
||||
if (result) perror("ioctl");
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (!*network) {
|
||||
struct sockaddr_ipx ipxs;
|
||||
int maxplen=sizeof(struct sockaddr_ipx);
|
||||
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));
|
||||
ipxs.sipx_family=AF_IPX;
|
||||
if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1){
|
||||
perror("EMUTLI:init_ipx");
|
||||
result = -1;
|
||||
} else {
|
||||
if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){
|
||||
perror("EMUTLI:init_ipx");
|
||||
result = -1;
|
||||
} else *network=ntohl(ipxs.sipx_network);
|
||||
}
|
||||
if (sock > -1) close(sock);
|
||||
}
|
||||
#endif
|
||||
close(sock);
|
||||
if (result) exit(1);
|
||||
result = ioctl(sock, mode, id);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
return(result);
|
||||
}
|
||||
|
||||
void exit_ipx(char *devname, uint32 network, int frame)
|
||||
|
||||
static void del_special_net(int special, char *devname, int frame)
|
||||
/* specials = */
|
||||
/* IPX_SPECIAL_NONE */
|
||||
/* IPX_INTERNAL */
|
||||
/* IPX_PRIMARY */
|
||||
/* devname + frame only if not IPX_INTERNAL */
|
||||
{
|
||||
if (have_ipx_started) {
|
||||
int sock=-1;
|
||||
int result=-1;
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock > -1) {
|
||||
struct ifreq id;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int i;
|
||||
memset(&id, 0, sizeof(struct ifreq));
|
||||
strcpy(id.ifr_name, devname);
|
||||
sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (socket < 0) {
|
||||
perror("EMUTLI:exit_ipx");
|
||||
return;
|
||||
}
|
||||
/* Switch DEBUG off */
|
||||
locipxdebug = 0;
|
||||
set_sock_debug(sock);
|
||||
|
||||
/* remove routes */
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
(void) ioctl(sock, SIOCSIFADDR, &id);
|
||||
|
||||
sipx->sipx_special = IPX_PRIMARY;
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
if (special != IPX_INTERNAL) {
|
||||
if (devname && *devname) strcpy(id.ifr_name, devname);
|
||||
sipx->sipx_type = frame;
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = special;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
(void) ioctl(sock, SIOCSIFADDR, &id);
|
||||
x_ioctl(sock, SIOCSIFADDR, &id);
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
|
||||
void myipx_route_add(unsigned char *dest_net,
|
||||
unsigned char *route_net,
|
||||
unsigned char *route_node)
|
||||
#define del_internal_net() \
|
||||
del_special_net(IPX_INTERNAL, NULL, 0)
|
||||
#define del_interface(devname, frame) \
|
||||
del_special_net(IPX_SPECIAL_NONE, (devname), (frame))
|
||||
|
||||
static void add_special_net(int special,
|
||||
char *devname, int frame, uint32 netnum, uint32 node)
|
||||
{
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock > -1) {
|
||||
struct ifreq id;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
memset(&id, 0, sizeof(struct ifreq));
|
||||
if (special != IPX_INTERNAL){
|
||||
if (devname && *devname) strcpy(id.ifr_name, devname);
|
||||
sipx->sipx_type = frame;
|
||||
} else {
|
||||
uint32 xx=htonl(node);
|
||||
memcpy(sipx->sipx_node+2, &xx, 4);
|
||||
}
|
||||
sipx->sipx_network = htonl(netnum);
|
||||
sipx->sipx_special = special;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_CRTITF;
|
||||
x_ioctl(sock, SIOCSIFADDR, &id);
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
#define add_internal_net(netnum, node) \
|
||||
add_special_net(IPX_INTERNAL, NULL, 0, (netnum), (node))
|
||||
|
||||
#define add_device_net(devname, frame, netnum) \
|
||||
add_special_net(IPX_SPECIAL_NONE, (devname), (frame), (netnum), 0)
|
||||
|
||||
#define add_primary_net(devname, frame, netnum) \
|
||||
add_special_net(IPX_PRIMARY, (devname), (frame), (netnum), 0)
|
||||
|
||||
int init_ipx(uint32 network, uint32 node, int ipx_debug)
|
||||
{
|
||||
int result=-1;
|
||||
int sock=sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (socket < 0) {
|
||||
errorp(0, "EMUTLI:init_ipx", NULL);
|
||||
exit(1);
|
||||
} else {
|
||||
set_sock_debug(sock);
|
||||
close(sock);
|
||||
result=0;
|
||||
/* makes new internal net */
|
||||
if (network) {
|
||||
del_internal_net();
|
||||
add_internal_net(network, node);
|
||||
have_ipx_started++;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
void exit_ipx(int full)
|
||||
{
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock > -1) {
|
||||
/* Switch DEBUG off */
|
||||
locipxdebug = 0;
|
||||
set_sock_debug(sock);
|
||||
close(sock);
|
||||
}
|
||||
if (have_ipx_started && full) del_internal_net();
|
||||
}
|
||||
|
||||
int init_dev(char *devname, int frame, uint32 network)
|
||||
{
|
||||
if (!network) return(0);
|
||||
del_interface(devname, frame);
|
||||
if (!have_ipx_started) {
|
||||
have_ipx_started++;
|
||||
add_primary_net(devname, frame, network);
|
||||
} else
|
||||
add_device_net(devname, frame, network);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void exit_dev(char *devname, int frame)
|
||||
{
|
||||
del_interface(devname, frame);
|
||||
}
|
||||
|
||||
int get_ipx_addr(ipxAddr_t *addr)
|
||||
{
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
int result=-1;
|
||||
if (sock > -1) {
|
||||
struct sockaddr_ipx ipxs;
|
||||
int maxplen=sizeof(struct sockaddr_ipx);
|
||||
result=0;
|
||||
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));
|
||||
ipxs.sipx_family=AF_IPX;
|
||||
if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1){
|
||||
errorp(0, "EMUTLI:bind", NULL);
|
||||
result = -1;
|
||||
} else {
|
||||
if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){
|
||||
errorp(0, "EMUTLI:init_ipx:getsockname", NULL);
|
||||
result = -1;
|
||||
} else sock2ipxadr(addr, &ipxs);
|
||||
}
|
||||
close(sock);
|
||||
} else errorp(0, "EMUTLI:bind", NULL);
|
||||
return(result);
|
||||
}
|
||||
|
||||
void ipx_route_add(uint32 dest_net,
|
||||
uint32 route_net,
|
||||
uint8 *route_node)
|
||||
{
|
||||
struct rtentry rd;
|
||||
int i;
|
||||
int result;
|
||||
int sock;
|
||||
/* Router */
|
||||
@ -270,26 +242,21 @@ void myipx_route_add(unsigned char *dest_net,
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
|
||||
|
||||
rd.rt_flags = RTF_GATEWAY;
|
||||
memcpy(&(st->sipx_network), dest_net, IPX_NET_SIZE);
|
||||
memcpy(&(sr->sipx_network), route_net, IPX_NET_SIZE);
|
||||
|
||||
st->sipx_network = htonl(dest_net);
|
||||
sr->sipx_network = htonl(route_net);
|
||||
memcpy(sr->sipx_node, route_node, IPX_NODE_SIZE);
|
||||
|
||||
if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){
|
||||
perror("EMUTLI:myipx_route_add");
|
||||
errorp(0, "EMUTLI:ipx_route_add", NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
sr->sipx_family = st->sipx_family = AF_IPX;
|
||||
i = 0;
|
||||
do {
|
||||
result = ioctl(sock, SIOCADDRT, &rd);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result) {
|
||||
if ( 0 != (result = x_ioctl(sock, SIOCADDRT, &rd))) {
|
||||
switch (errno) {
|
||||
case ENETUNREACH:
|
||||
fprintf(stderr, "Router network (%08X) not reachable.\n",
|
||||
errorp(0, "ROUTE ADD", "Router network (%08X) not reachable.\n",
|
||||
htonl(sr->sipx_network));
|
||||
break;
|
||||
|
||||
@ -298,17 +265,16 @@ void myipx_route_add(unsigned char *dest_net,
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("add route ioctl");
|
||||
errorp(0, "ROUTE ADD", NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void myipx_route_del(unsigned char *net)
|
||||
void ipx_route_del(uint32 net)
|
||||
{
|
||||
struct rtentry rd;
|
||||
int i;
|
||||
int result;
|
||||
int sock;
|
||||
/* Router */
|
||||
@ -316,21 +282,14 @@ void myipx_route_del(unsigned char *net)
|
||||
/* Target */
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
|
||||
rd.rt_flags = RTF_GATEWAY;
|
||||
memcpy(&(st->sipx_network), net, IPX_NET_SIZE);
|
||||
st->sipx_network = htonl(net);
|
||||
|
||||
if ( (sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0){
|
||||
perror("EMUTLI:myipx_route_del");
|
||||
errorp(0, "EMUTLI:ipx_route_del", NULL);
|
||||
return;
|
||||
}
|
||||
sr->sipx_family = st->sipx_family = AF_IPX;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
result = ioctl(sock, SIOCDELRT, &rd);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
/* errors doesn't matter here */
|
||||
|
||||
x_ioctl(sock, SIOCDELRT, &rd);
|
||||
close(sock);
|
||||
}
|
||||
|
||||
@ -340,13 +299,11 @@ int t_open(char *name, int open_mode, char * p)
|
||||
int opt=1;
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock < 0) return(sock);
|
||||
set_sock_debug(sock); /* debug switch */
|
||||
|
||||
/* NUN DEBUG ein bzw. ausschalten */
|
||||
set_sock_debug(sock);
|
||||
|
||||
/* NUN Broadcast erlauben */
|
||||
/* Now allow broadcast */
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt,sizeof(opt))==-1){
|
||||
perror("setsockopt SO_BROADCAST");
|
||||
errorp(0, "setsockopt SO_BROADCAST", NULL);
|
||||
close(sock);
|
||||
return(-1);
|
||||
}
|
||||
@ -367,18 +324,16 @@ int t_bind(int sock, struct t_bind *a_in, struct t_bind *a_out)
|
||||
ipxs.sipx_network = 0L;
|
||||
|
||||
if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1) {
|
||||
char xx[100];
|
||||
sprintf(xx, "TLI-BIND socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port)));
|
||||
perror(xx);
|
||||
errorp(0, "TLI-BIND", "socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port)));
|
||||
return(-1);
|
||||
}
|
||||
if (a_out != (struct t_bind*) NULL) {
|
||||
if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){
|
||||
perror("TLI-GETSOCKNAME");
|
||||
errorp(0, "TLI-GETSOCKNAME", NULL);
|
||||
return(-1);
|
||||
}
|
||||
sock2ipxadr((ipxAddr_t*) (a_out->addr.buf), &ipxs);
|
||||
DPRINTF(("T_BIND ADR=%s\n", visable_ipx_adr((ipxAddr_t *) a_out->addr.buf ) ));
|
||||
XDPRINTF((2,"T_BIND ADR=%s\n", visable_ipx_adr((ipxAddr_t *) a_out->addr.buf ) ));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@ -392,7 +347,7 @@ int t_unbind(int sock)
|
||||
int t_errno=0;
|
||||
void t_error(char *s)
|
||||
{
|
||||
perror(s);
|
||||
errorp(0, "t_error", s);
|
||||
t_errno=0;
|
||||
}
|
||||
|
||||
@ -435,8 +390,8 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
|
||||
time_out.tv_sec = 0;
|
||||
time_out.tv_usec = timeout*1000;
|
||||
}
|
||||
result = select(high_f+1, &readfs, NULL, NULL, &time_out);
|
||||
if (result < 0) return(-1);
|
||||
if (0 > (result = select(high_f+1, &readfs, NULL, NULL, &time_out)))
|
||||
return(-1);
|
||||
if (result) {
|
||||
int rest=result;
|
||||
k = (int)nfds;
|
||||
@ -444,7 +399,7 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
|
||||
while (k--){
|
||||
if (p->fd > -1 && FD_ISSET(p->fd, &readfs)){
|
||||
p->revents = POLLIN;
|
||||
if (! --rest) break; /* fertig */
|
||||
if (! --rest) break; /* ready */
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@ -487,12 +442,6 @@ int t_sndudata(int fd, struct t_unitdata *ud)
|
||||
|
||||
result = sendto(fd,(void *)ud->udata.buf,
|
||||
ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs));
|
||||
|
||||
if (result<0) {
|
||||
char xx[100];
|
||||
sprintf(xx, "t_sndudata->result=%d, errno=%d\n", result, errno);
|
||||
perror(xx);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
29
emutli.h
29
emutli.h
@ -42,6 +42,13 @@ typedef struct {
|
||||
((char *)(a))[5] == ((char*)(b))[5] \
|
||||
)
|
||||
|
||||
#define IPXCMPNET(a, b) ( \
|
||||
((char *)(a))[0] == ((char*)(b))[0] && \
|
||||
((char *)(a))[1] == ((char*)(b))[1] && \
|
||||
((char *)(a))[2] == ((char*)(b))[2] && \
|
||||
((char *)(a))[3] == ((char*)(b))[3] \
|
||||
)
|
||||
|
||||
struct netbuf {
|
||||
unsigned int maxlen;
|
||||
unsigned int len;
|
||||
@ -87,22 +94,22 @@ extern int t_rcvudata(int fd, struct t_unitdata *ud, int *flags);
|
||||
extern int t_rcvuderr(int fd, struct t_uderr *ud);
|
||||
extern int t_sndudata(int fd, struct t_unitdata *ud);
|
||||
|
||||
extern int init_ipx(char *device, uint32 *network,
|
||||
uint32 intnet,
|
||||
int frame,
|
||||
char *frame_name,
|
||||
int ipx_debug);
|
||||
|
||||
extern void exit_ipx(char *devname, uint32 network, int frame);
|
||||
extern int init_ipx(uint32 network, uint32 node, int ipx_debug);
|
||||
extern void exit_ipx(int full);
|
||||
|
||||
extern void myipx_route_add(unsigned char *dest_net,
|
||||
unsigned char *route_net,
|
||||
unsigned char *route_node);
|
||||
extern int init_dev(char *devname, int frame, uint32 network);
|
||||
extern void exit_dev(char *devname, int frame);
|
||||
|
||||
extern void myipx_route_del(unsigned char *net);
|
||||
extern int get_ipx_addr(ipxAddr_t *addr);
|
||||
|
||||
extern void set_emu_tli(int ipx_debug);
|
||||
extern void ipx_route_add(uint32 dest_net,
|
||||
uint32 route_net,
|
||||
uint8 *route_node);
|
||||
|
||||
extern void ipx_route_del(uint32 net);
|
||||
|
||||
extern void set_emu_tli(void);
|
||||
|
||||
#ifndef IPX_FRAME_8022
|
||||
#define OLD_KERNEL_IPX 1
|
||||
|
@ -1,9 +1,11 @@
|
||||
/* config.h: 22-Nov-95 */
|
||||
/* this config is needed by make and by cc */
|
||||
#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 */
|
||||
/* config.h: 10-Dec-95 */
|
||||
/* some of this config is needed by make, others by cc */
|
||||
#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 MAX_CONNECTIONS 5 /* max. Number of Connections */
|
||||
#define MAX_NW_VOLS 10 /* max. Volumes */
|
||||
|
||||
#define MAX_NET_DEVICES 1 /* max. Netdevices, frames */
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
# (C)opyright 1993, 1995, Martin Stover, Softwareentwicklung, Marburg
|
||||
# last change: 20-Dec-95
|
||||
# MAR.S NW-Server Emulator
|
||||
# Einfache Konfiguration, alles ab # ist Kommentar.
|
||||
# Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt.
|
||||
# simple configuration, all after # is ignored.
|
||||
# Every entry begins with a number and then the meet follows.
|
||||
# every entry begins with a number and then the meet follows.
|
||||
# entry 1 VOLUMES (max. 5) entry 1
|
||||
# Volumename Volumepath Options (k=lowercase)
|
||||
1 SYS /u3/SYS/ # SYS 1
|
||||
####################################
|
||||
# Die folgenden Volumes sind optional.
|
||||
# the following volumes are optional.
|
||||
#1 SYS1 /u3/SYS1/ # SYS 2
|
||||
#1 SYS1 /u3/SYS1/ # SYS 2 upshift
|
||||
#1 TMP /tmp/ k # TMP downshift
|
||||
#1 CD /cdrom k # CDROM allways downshift
|
||||
#1 CD /cdrom k # CDROM downshift
|
||||
# Falls lowercase nicht gesetzt ist, werden GROSSBUCHSTABEN erwartet.
|
||||
# If lowercase is not set then all filenames are upshift.
|
||||
# SYS, der Name darf auch anders lauten, muss
|
||||
@ -20,34 +21,68 @@
|
||||
# LOGIN, PUBLIC, SYSTEM, MAIL.
|
||||
# SYS, may be named diffent but must be setup and must
|
||||
# contains the following Directories: LOGIN, PUBLIC, SYSTEM, MAIL
|
||||
#############################
|
||||
######################################
|
||||
# Eintrag 2 fuer den Servername.
|
||||
# falls nicht gesetzt, wird hostname (in GROSSBUCHSTABEN) verwendet.
|
||||
# entry 2 for the servername. If not set, then the hostname (upshift)
|
||||
# will be taken.
|
||||
#2 MAR1 # Servername
|
||||
# entry 4: #
|
||||
# NETWORK NUMBER, DEVICE, Frame-Typ
|
||||
4 0x10 eth0 802.3
|
||||
# Frames=ethernet_ii od. 802.2 od. 802.3 od SNAP (default 802.3)
|
||||
# ACHTUNG ethernet_ii geht leider seit LINUX > V 1.1.44 nicht mehr.
|
||||
# aktuell getestet nur mit 802.3 !!!!!
|
||||
# actual testet with 802.3 !!
|
||||
######################################
|
||||
# z.Z. werden _alle_ Connections mit folgender UID bzw. GID gestartet.
|
||||
# wird noch geaendert werden.
|
||||
# _all_ connections will be started with the following UID and GID.
|
||||
# will be change one time.
|
||||
# next entry for later use, not yet supported !!
|
||||
# the ipx kernel code must changed first, to do good routing !!
|
||||
# INTERNAL NET [NODE]
|
||||
###3 0x999999 1 # Node default 1
|
||||
######################################
|
||||
# entry 4: # for DEVICE(S)
|
||||
# if your ipx is allready up, then entry 4 must be removed.
|
||||
# NETWORK NUMBER, DEVICE, Frame-Typ TICS (default 1)
|
||||
4 0x10 eth0 802.3 1
|
||||
# Frames=ethernet_ii, 802.2, 802.3, SNAP (default 802.3)
|
||||
# testet with 802.3
|
||||
5 0 # don't = 0, do = 1, save ipx-routes after server is down.
|
||||
######################################
|
||||
# some clients are running better, if the server tells
|
||||
# that it is a 3.11 Server, although many calls
|
||||
# (namespace services) of a real 3.11 Server are missing yet.
|
||||
6 0 # tells server version: 2.15=0, 3.11=1
|
||||
######################################
|
||||
# GID and UID for _minimal_ rights
|
||||
# will be used for not logins
|
||||
10 200 # GID
|
||||
11 201 # UID
|
||||
#############################
|
||||
# entry 21 for simple print queues, dynamic
|
||||
# the following passwords can be removed after the first
|
||||
# start, because these entries will be inserted (crypted) into
|
||||
# the bindery
|
||||
# one entry 12 for SUPERVISOR
|
||||
## NW-Name UNIX-Name [PASSWORD]
|
||||
12 SUPERVISOR root MYPW # Supervisor
|
||||
#############################
|
||||
# more entries 13 for other user(s)
|
||||
## NW-Name UNIX-Name [PASSWORD]
|
||||
#13 MAR mar # others
|
||||
#13 ALF mar # others
|
||||
#############################
|
||||
# entry 21 for simple print queues
|
||||
# the queue Directory must exist before printing !!!
|
||||
# QUEUE NAME, Q_DIRECTORY, UNIX-print-command (pipe)
|
||||
21 Q1 SYS:/PRINT/Q1 lpr
|
||||
#21 Q2 SYS:/PRINT/Q2 lpr -C printer2
|
||||
#############################
|
||||
# >= 100 debug flags
|
||||
100 0 # debug IPX KERNEL (0 / 1)
|
||||
# >= 100 debug flags,
|
||||
# 0=nodebug, 1=mindebug(errors), 99=maxdebug
|
||||
100 0 # debug IPX KERNEL (0 | 1)
|
||||
101 1 # debug NWSERV
|
||||
102 0 # debug NCPSERV
|
||||
103 0 # debug NWCONN
|
||||
104 0 # debug (start) NWCLIENT
|
||||
#############################
|
||||
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
|
||||
#############################
|
||||
210 10 # 1 .. 600 (default 10) seconds after server really goes down
|
||||
# # after a down command
|
||||
|
||||
|
||||
|
29
makefile.unx
29
makefile.unx
@ -1,13 +1,15 @@
|
||||
# makefile.unx 15-Nov-95
|
||||
# makefile.unx 20-Dec-95
|
||||
VPATH=..
|
||||
O=.o
|
||||
C=.c
|
||||
|
||||
DEBUG=-DDB
|
||||
V_H=0
|
||||
V_L=95
|
||||
V_L=96
|
||||
P_L=0
|
||||
DISTRIB=mars_nwe
|
||||
PATCHF=$(DISTRIB)p$(V_H).$(V_L)
|
||||
DISTRIBF=$(DISTRIB)-$(V_H).$(V_L)
|
||||
PATCHF=$(DISTRIBF).pl$(P_L)
|
||||
STERN=*
|
||||
|
||||
#if 0
|
||||
@ -77,10 +79,10 @@ M_PATHNAME_PROGS="."
|
||||
#endif
|
||||
|
||||
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
|
||||
OBJ2= $(OBJ1)
|
||||
OBJ2= $(OBJ1) nwroute$(O)
|
||||
#nwdbm$(O)
|
||||
OBJ3= $(OBJ1) connect$(O)
|
||||
OBJ4= $(OBJ1) nwdbm$(O)
|
||||
OBJ3= $(OBJ1) connect$(O) namspace$(O)
|
||||
OBJ4= $(OBJ1) nwdbm$(O) nwcrypt$(O)
|
||||
OBJ5= $(OBJ1)
|
||||
|
||||
OBJS= net1$(O) tools$(O) connect$(O) nwdbm$(O) \
|
||||
@ -155,11 +157,14 @@ n_diff: n_clean1
|
||||
makefile.unx \
|
||||
Makefile \
|
||||
COPYING \
|
||||
CHANGES \
|
||||
README \
|
||||
README.ger \
|
||||
INSTALL \
|
||||
INSTALL.ger \
|
||||
$(DISTRIB).lsm \
|
||||
$(DISTRIB)/. \
|
||||
; rm -f $(DISTRIB)/config.h \
|
||||
; ln -f \
|
||||
examples/$(STERN) \
|
||||
$(DISTRIB)/examples/. \
|
||||
@ -169,15 +174,15 @@ n_diff: n_clean1
|
||||
|
||||
n_distrib: n_diff
|
||||
-mkdir /tmp/x
|
||||
cd .. && (tar cvzf $(DISTRIB).tgz $(DISTRIB) \
|
||||
; uue $(DISTRIB).tgz \
|
||||
cd .. && (tar cvzf $(DISTRIBF).tgz $(DISTRIB) \
|
||||
; uue $(DISTRIBF).tgz; mv -f $(DISTRIB)-$(V_H).uue $(DISTRIBF).uue \
|
||||
; cp -a $(DISTRIB)/$(DISTRIB).lsm /tmp/yy \
|
||||
; echo "" >> /tmp/yy \
|
||||
; echo "" >> /tmp/yy \
|
||||
; cat $(DISTRIB).uue >> /tmp/yy \
|
||||
; cat $(DISTRIBF).uue >> /tmp/yy \
|
||||
; chmod 664 /tmp/yy \
|
||||
; rm $(DISTRIB).uue \
|
||||
; mv $(DISTRIB).tgz /tmp/x/. \
|
||||
; rm $(DISTRIBF).uue \
|
||||
; mv $(DISTRIBF).tgz /tmp/x/. \
|
||||
; cp -a $(DISTRIB)/$(DISTRIB).lsm /tmp/x/. \
|
||||
; cd obj )
|
||||
|
||||
@ -186,6 +191,8 @@ n_distrib_bin:
|
||||
$(PROGS) \
|
||||
COPYING \
|
||||
INSTALL \
|
||||
INSTALL.ger \
|
||||
CHANGES \
|
||||
README \
|
||||
README.ger \
|
||||
$(DISTRIB).lsm \
|
||||
|
17
mars_nwe.lsm
17
mars_nwe.lsm
@ -1,15 +1,16 @@
|
||||
Begin3
|
||||
Title: mars_nwe
|
||||
Version: 0.95
|
||||
Entered-date: 22-Nov-95
|
||||
Version: 0.96
|
||||
Entered-date: 20-Dec-95
|
||||
Description: simple novell-server-emulator (src),beta
|
||||
needs no kernelchanges, usefull for testing ipx
|
||||
file-services, bindery-services, printing-services
|
||||
Keywords: novell, netware, server, ipx, ncp, tli
|
||||
Author: mstover@kool.f.eunet.de (Martin Stover)
|
||||
Maintained-by: mstover@kool.f.eunet.de (Martin Stover)
|
||||
Primary-site: linux01.gwdg.de /pub/???
|
||||
80kB mars_nwe.tgz
|
||||
Platforms: Linux (1.2.xx testet, others should work)
|
||||
Keywords: novell, netware, unixware, server, ipx, ncp, tli
|
||||
Author: mstover@freeway.de (Martin Stover)
|
||||
Maintained-by: mstover@freeway.de (Martin Stover)
|
||||
Primary-site: linux01.gwdg.de /pub/ncpfs
|
||||
80kB mars_nwe-0.96.tgz
|
||||
Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware
|
||||
Platforms: Linux (1.2.xx, 1.3.32 testet, others should work)
|
||||
Copying-policy: GNU
|
||||
End
|
||||
|
97
namspace.c
Normal file
97
namspace.c
Normal file
@ -0,0 +1,97 @@
|
||||
/* namspace.c 26-Nov-95 : NameSpace Services, mars_nwe */
|
||||
|
||||
/* (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 nw_generate_dir_path(uint8 *nwpathstruct,
|
||||
uint8 *ns_dir_base, uint8 *dos_dir_base)
|
||||
/* returns Volume Number >=0 or errcode < 0 if error */
|
||||
{
|
||||
return(-0xfb); /* TODO: complete call */
|
||||
}
|
||||
|
||||
|
||||
int handle_func_0x57(uint8 *p, uint8 *responsedata)
|
||||
{
|
||||
int result = -0xfb; /* unknown request */
|
||||
int ufunc = (int) *p++; /* now p locates at 4 byte boundary */
|
||||
int namspace = (int) *p; /* for most calls */
|
||||
switch (ufunc) {
|
||||
case 0x02 : /* Initialize Search */
|
||||
{
|
||||
/* NW PATH STRUC */
|
||||
}
|
||||
break;
|
||||
case 0x07 : /* Modify File or Dir Info */
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x09 : /* Set short Dir Handle*/
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x15 : /* Get Path String from short dir neu*/
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x16 : /* Generate Dir BASE and VolNumber */
|
||||
{
|
||||
uint8 *nwpathstruct = p+3;
|
||||
struct OUTPUT {
|
||||
uint8 ns_dir_base[4]; /* BASEHANDLE */
|
||||
uint8 dos_dir_base[4]; /* BASEHANDLE */
|
||||
uint8 volume; /* Volumenumber*/
|
||||
} *xdata= (struct OUTPUT*)responsedata;
|
||||
result = nw_generate_dir_path(nwpathstruct,
|
||||
xdata->ns_dir_base, xdata->dos_dir_base);
|
||||
|
||||
if (result >-1) {
|
||||
xdata->volume = result;
|
||||
result = sizeof(struct OUTPUT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0c : /* alloc short dir Handle */
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x1a : /* Get Huge NS Info new*/
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x1c : /* GetFullPathString new*/
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x1d : /* GetEffDirRights new */
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default : result = -0xfb; /* unknown request */
|
||||
} /* switch */
|
||||
return(result);
|
||||
}
|
394
ncpserv.c
394
ncpserv.c
@ -1,4 +1,4 @@
|
||||
/* ncpserv.c, 22-Nov-95 */
|
||||
/* ncpserv.c, 19-Dec-95 */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -19,13 +19,7 @@
|
||||
|
||||
#include "net.h"
|
||||
#include "nwdbm.h"
|
||||
|
||||
int conn_gid;
|
||||
int conn_uid;
|
||||
|
||||
int nwconn_debug=0;
|
||||
int ipxdebug=0;
|
||||
|
||||
static struct pollfd polls[2];
|
||||
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;
|
||||
@ -37,33 +31,66 @@ static ipxAddr_t my_addr;
|
||||
static int rcv_flags = 0;
|
||||
static char my_nwname[50];
|
||||
static time_t akttime;
|
||||
static int server_goes_down=0;
|
||||
|
||||
static void write_to_nwserv(int what, int connection, char *data, int size)
|
||||
static void write_to_nwserv(int what, int connection, int mode,
|
||||
char *data, int size)
|
||||
{
|
||||
switch (what) {
|
||||
case 0x2222 : /* insert wdog connection */
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
write(FD_NWSERV, &connection, sizeof(int));
|
||||
write(FD_NWSERV, &size, sizeof(int));
|
||||
write(FD_NWSERV, data, size); /* ipxAddr_t */
|
||||
break;
|
||||
|
||||
case 0x4444 : /* tell the wdog there's no need to look */
|
||||
case 0x6666 : /* the connection ist closed */
|
||||
case 0x8888 : /* send to client that server holds message */
|
||||
case 0x4444 : /* tell the wdog there's no need to look 0 */
|
||||
/* fast activate wdog to free connection 1 */
|
||||
/* slow activate wdog to free connection 2 */
|
||||
/* the connection ist closed 99 */
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
write(FD_NWSERV, &connection, sizeof(int));
|
||||
write(FD_NWSERV, &mode, sizeof(int));
|
||||
break;
|
||||
|
||||
case 0x6666 : /* send to client that server holds message */
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
write(FD_NWSERV, &connection, sizeof(int));
|
||||
break;
|
||||
|
||||
case 0xffff : /* say nwserv to down the server */
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
break;
|
||||
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
|
||||
#define nwserv_insert_wdog(connection, adr) \
|
||||
write_to_nwserv(0x2222, (connection), 0, (adr), sizeof(ipxAddr_t))
|
||||
|
||||
#define nwserv_handle_wdog(connection, mode) \
|
||||
write_to_nwserv(0x4444, (connection), (mode), NULL, 0)
|
||||
|
||||
#define nwserv_reset_wdog(connection) \
|
||||
write_to_nwserv(0x4444, (connection), 0, NULL, 0)
|
||||
|
||||
#define nwserv_close_wdog(connection) \
|
||||
write_to_nwserv(0x4444, (connection), 99, NULL, 0)
|
||||
|
||||
#define nwserv_handle_msg(connection) \
|
||||
write_to_nwserv(0x6666, (connection), 0, NULL, 0)
|
||||
|
||||
#define nwserv_down_server() \
|
||||
write_to_nwserv(0xffff, 0, 0, NULL, 0)
|
||||
|
||||
static int open_ncp_socket()
|
||||
{
|
||||
struct t_bind bind;
|
||||
ncp_fd=t_open("/dev/ipx", O_RDWR, NULL);
|
||||
if (ncp_fd < 0) {
|
||||
t_error("t_open !Ok");
|
||||
if (nw_debug) t_error("t_open !Ok");
|
||||
return(-1);
|
||||
}
|
||||
U16_TO_BE16(SOCK_NCP, my_addr.sock); /* NCP_SOCKET */
|
||||
@ -72,7 +99,7 @@ static int open_ncp_socket()
|
||||
bind.addr.buf = (char*)&my_addr;
|
||||
bind.qlen = 0; /* immer */
|
||||
if (t_bind(ncp_fd, &bind, &bind) < 0){
|
||||
t_error("t_bind in open_ncp_socket !OK");
|
||||
if (nw_debug) t_error("t_bind in open_ncp_socket !OK");
|
||||
close(ncp_fd);
|
||||
return(-1);
|
||||
}
|
||||
@ -86,7 +113,6 @@ typedef struct {
|
||||
uint32 object_id; /* logged object */
|
||||
/* 0 = not logged in */
|
||||
uint8 crypt_key[8]; /* password generierung */
|
||||
|
||||
uint8 message[60]; /* saved BCastmessage */
|
||||
int sequence; /* previous sequence */
|
||||
int retry; /* one reply being serviced is sent */
|
||||
@ -95,12 +121,13 @@ typedef struct {
|
||||
} CONNECTION;
|
||||
|
||||
static CONNECTION connections[MAX_CONNECTIONS];
|
||||
static int anz_connect=0; /* aktuelle Connections */
|
||||
static int anz_connect=0; /* actual anz connections */
|
||||
|
||||
static int new_conn_nr(void)
|
||||
{
|
||||
int j = -1;
|
||||
if (!anz_connect){ /* alles initialisieren */
|
||||
int not_logged=-1;
|
||||
if (!anz_connect){ /* init all */
|
||||
j = MAX_CONNECTIONS;
|
||||
while (j--) {
|
||||
connections[j].fd = -1;
|
||||
@ -111,13 +138,26 @@ static int new_conn_nr(void)
|
||||
}
|
||||
j = -1;
|
||||
while (++j < MAX_CONNECTIONS) {
|
||||
if (connections[j].fd < 0) {
|
||||
connections[j].message[0] = '\0';
|
||||
CONNECTION *c=&(connections[j]);
|
||||
if (c->fd < 0) {
|
||||
c->message[0] = '\0';
|
||||
if (++j > anz_connect) anz_connect=j;
|
||||
return(j);
|
||||
}
|
||||
}
|
||||
return(0); /* nichts frei */
|
||||
/* nothing free */
|
||||
j=MAX_CONNECTIONS;
|
||||
while (j--) {
|
||||
CONNECTION *c=&(connections[j]);
|
||||
if (!c->object_id) { /* NOT LOGGED IN */
|
||||
/* makes wdog test faster */
|
||||
nwserv_handle_wdog(j+1, 1);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
j=0;
|
||||
while (j++ < MAX_CONNECTIONS) nwserv_handle_wdog(j, 2);
|
||||
return(0); /* nothing free */
|
||||
}
|
||||
|
||||
int free_conn_nr(int nr)
|
||||
@ -142,7 +182,7 @@ int find_conn_nr(ipxAddr_t *addr)
|
||||
|
||||
void clear_connection(int conn)
|
||||
{
|
||||
write_to_nwserv(0x6666, conn, NULL, 0);
|
||||
nwserv_close_wdog(conn);
|
||||
if (conn > 0 && --conn < anz_connect) {
|
||||
CONNECTION *c = &connections[conn];
|
||||
if (c->fd > -1) {
|
||||
@ -172,14 +212,14 @@ int find_get_conn_nr(ipxAddr_t *addr)
|
||||
int fds[2];
|
||||
memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t));
|
||||
if (pipe(fds) < 0) {
|
||||
perror("find_get_conn_nr, pipe");
|
||||
errorp(0, "find_get_conn_nr, pipe", NULL);
|
||||
free_conn_nr(connection);
|
||||
return(0);
|
||||
} else {
|
||||
int akt_pid = getpid();
|
||||
int pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("find_get_conn_nr, fork");
|
||||
errorp(0, "find_get_conn_nr, fork", NULL);
|
||||
free_conn_nr(connection);
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
@ -192,10 +232,6 @@ int find_get_conn_nr(ipxAddr_t *addr)
|
||||
char pidstr[20];
|
||||
char connstr[20];
|
||||
char addrstr[100];
|
||||
char gidstr[10];
|
||||
char uidstr[10];
|
||||
char db_str1[5];
|
||||
char db_str2[5];
|
||||
int j = 2;
|
||||
close(fds[1]); /* no writing */
|
||||
dup2(fds[0], 0); /* becomes stdin */
|
||||
@ -205,20 +241,10 @@ int find_get_conn_nr(ipxAddr_t *addr)
|
||||
|
||||
sprintf(pidstr, "%d", akt_pid);
|
||||
sprintf(connstr, "%d", connection);
|
||||
|
||||
sprintf(gidstr, "%d", conn_gid);
|
||||
sprintf(uidstr, "%d", conn_uid);
|
||||
|
||||
sprintf(db_str1, "%d", nwconn_debug);
|
||||
|
||||
sprintf(db_str2, "%d", ipxdebug);
|
||||
|
||||
ipx_addr_to_adr(addrstr, addr);
|
||||
|
||||
execl(get_exec_path(pathname, progname), progname,
|
||||
pidstr, addrstr, connstr,
|
||||
gidstr, uidstr,
|
||||
db_str1,
|
||||
db_str2, NULL);
|
||||
pidstr, addrstr, connstr, NULL);
|
||||
exit(1); /* normaly not reached */
|
||||
}
|
||||
c->pid = pid;
|
||||
@ -228,10 +254,23 @@ int find_get_conn_nr(ipxAddr_t *addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connection) write_to_nwserv(0x2222, connection, (char*)addr, sizeof(ipxAddr_t));
|
||||
if (connection) nwserv_insert_wdog(connection, (char*)addr);
|
||||
return(connection);
|
||||
}
|
||||
|
||||
static void sent_down_message(void)
|
||||
{
|
||||
int k = -1;
|
||||
server_goes_down++;
|
||||
while (++k < anz_connect) {
|
||||
CONNECTION *cn=&connections[k];
|
||||
if (cn->fd > -1) {
|
||||
strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58);
|
||||
nwserv_handle_msg(k+1);
|
||||
}
|
||||
} /* while */
|
||||
}
|
||||
|
||||
static void get_login_time(uint8 login_time[], CONNECTION *cx)
|
||||
{
|
||||
struct tm *s_tm = localtime(&(cx->t_login));
|
||||
@ -262,7 +301,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
uint8 connect_status= 0;
|
||||
int data_len = 0;
|
||||
|
||||
if (nw_debug){
|
||||
if (nw_debug > 1){
|
||||
int j = gelen - sizeof(NCPREQUEST);
|
||||
if (nw_debug){
|
||||
DPRINTF(("NCP 0x%x REQUEST:ufunc:0x%x\n", func, ufunc));
|
||||
@ -300,7 +339,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
strmaxcpy(cn->message, msg, min(58, msglen));
|
||||
result = 0; /* Ok */
|
||||
} else result = 0xfc; /* server holds message */
|
||||
write_to_nwserv(0x8888, connr+1, NULL, 0);
|
||||
nwserv_handle_msg(connr+1);
|
||||
one_found++;
|
||||
}
|
||||
*p++ = (uint8)result;
|
||||
@ -354,8 +393,8 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
case 0x11 : { /* Get FileServer Info */
|
||||
struct XDATA {
|
||||
uint8 servername[48];
|
||||
uint8 version; /* 3 */
|
||||
uint8 subversion; /* 11 */
|
||||
uint8 version; /* 2 or 3 */
|
||||
uint8 subversion; /* 15 or 11 */
|
||||
uint8 maxconnections[2];
|
||||
uint8 connection_in_use[2];
|
||||
uint8 max_volumes[2];
|
||||
@ -372,12 +411,23 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
uint8 internet_bridge_version;
|
||||
uint8 reserved[60];
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
int k, i;
|
||||
memset(xdata, 0, sizeof(struct XDATA));
|
||||
strcpy(xdata->servername, my_nwname);
|
||||
if (!tells_server_version) {
|
||||
xdata->version = 2;
|
||||
xdata->subversion = 15;
|
||||
} else {
|
||||
xdata->version = 3;
|
||||
xdata->subversion = 11;
|
||||
}
|
||||
i=0;
|
||||
for (k=0; k < anz_connect; k++) {
|
||||
if (connections[k].fd > -1) i++;
|
||||
}
|
||||
U16_TO_BE16(i, xdata->connection_in_use);
|
||||
U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections);
|
||||
U16_TO_BE16(anz_connect, xdata->connection_in_use);
|
||||
U16_TO_BE16(anz_connect, xdata->peak_connection);
|
||||
U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes);
|
||||
data_len = sizeof(struct XDATA);
|
||||
} break;
|
||||
@ -416,15 +466,19 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
upstr(obj.name);
|
||||
strmaxcpy(password, (char*)(p1+1),
|
||||
max(sizeof(password)-1, (int) *p1));
|
||||
DPRINTF(("LOGIN unencrypted PW NAME='%s', PASSW='%s'\n",
|
||||
DPRINTF(("TODO:LOGIN unencrypted PW NAME='%s', PASSW='%s'\n",
|
||||
obj.name, password));
|
||||
if (0 == (result = find_obj_id(&obj, 0))) {
|
||||
/* TODO: check password !!!!!!! */
|
||||
;;
|
||||
result = 0xff;
|
||||
}
|
||||
if (!result) {
|
||||
c->object_id = obj.id; /* actuell Object ID */
|
||||
c->t_login = akttime; /* u. login Time */
|
||||
get_guid(rdata+2, rdata+2+sizeof(int), obj.id);
|
||||
in_len=12 + 2*sizeof(int);
|
||||
return(-1); /* nwconn must do the rest */
|
||||
} else completition = (uint8) -result;
|
||||
} break;
|
||||
|
||||
@ -466,6 +520,8 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
uint8 *pp = responsedata;
|
||||
data_len = k;
|
||||
while (k--) *pp++ = *p++ = (uint8) rand();
|
||||
/* if all here are same (1 or 2) then the resulting key is */
|
||||
/* 00000000 */
|
||||
}
|
||||
break;
|
||||
|
||||
@ -476,14 +532,15 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
obj.type = GET_BE16(p);
|
||||
strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2));
|
||||
upstr(obj.name);
|
||||
DPRINTF(("LOGIN CRYPTED PW NAME='%s'\n",obj.name));
|
||||
if (0 == (result = find_obj_id(&obj, 0))) {
|
||||
/* TODO: check password !!!!!!! */
|
||||
;;
|
||||
}
|
||||
if (!result) {
|
||||
XDPRINTF((2, "LOGIN CRYPTED PW NAME='%s'\n",obj.name));
|
||||
if (0 == (result = find_obj_id(&obj, 0)))
|
||||
result=nw_test_passwd(obj.id, c->crypt_key, rdata);
|
||||
if (result > -1) {
|
||||
c->object_id = obj.id; /* actuell Object */
|
||||
c->t_login = akttime; /* and login time */
|
||||
get_guid(rdata+2, rdata+2+sizeof(int), obj.id);
|
||||
in_len=12 + 2*sizeof(int);
|
||||
return(-1); /* nwconn must do the rest */
|
||||
} else completition = (uint8) -result;
|
||||
}
|
||||
break;
|
||||
@ -538,8 +595,9 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
} break;
|
||||
|
||||
case 0x34 : { /* rename OBJECT, only SU */
|
||||
int result=-0xff;
|
||||
if (1 == c->object_id) {
|
||||
uint8 *p = rdata;
|
||||
int result;
|
||||
NETOBJ obj;
|
||||
uint8 newname[256];
|
||||
uint8 *p1 = p+3 + *(p+2); /* new Name Length */
|
||||
@ -547,6 +605,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2));
|
||||
strmaxcpy((char*)newname, (char*)(p1+1), (int) *(p1));
|
||||
result = nw_rename_obj(&obj, newname);
|
||||
}
|
||||
if (result) completition = (uint8) -result;
|
||||
} break;
|
||||
|
||||
@ -622,12 +681,15 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
|
||||
case 0x38 : { /* change Bindery Objekt Security */
|
||||
/* only SU ! */
|
||||
int result= -0xff;
|
||||
if (1 == c->object_id) {
|
||||
uint8 *p = rdata;
|
||||
int result;
|
||||
NETOBJ obj;
|
||||
obj.type = GET_BE16(p+1);
|
||||
strmaxcpy((char*)obj.name, (char*)(p+4), (int) *(p+3));
|
||||
result = nw_change_obj_security(&obj, (int)*p);
|
||||
}
|
||||
if (result < 0) completition = (uint8) -result;
|
||||
} break;
|
||||
|
||||
case 0x39 : { /* create Property */
|
||||
@ -751,9 +813,20 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
if (result) completition = (uint8) -result;
|
||||
} break;
|
||||
|
||||
|
||||
case 0x40: { /* change object password */
|
||||
;
|
||||
uint8 *p = rdata;
|
||||
NETOBJ obj;
|
||||
int result;
|
||||
obj.type = GET_BE16(p);
|
||||
strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2));
|
||||
upstr(obj.name);
|
||||
if (0 == (result = find_obj_id(&obj, 0))) {
|
||||
;;
|
||||
}
|
||||
if (result < 0) completition = (uint8) -result;
|
||||
DPRINTF(("TODO: Change Obj PW from OBJECT='%s', result=%d\n",
|
||||
obj.name, result));
|
||||
completition=0xff;
|
||||
} break;
|
||||
|
||||
case 0x41 : { /* add Bindery Object to Set */
|
||||
@ -837,7 +910,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
if (!result) {
|
||||
*xdata = obj.security;
|
||||
U32_TO_BE32(obj.id, (xdata+1));
|
||||
DPRINTF(("ACCESS LEVEL:=0x%x, obj=0x%lx\n",
|
||||
XDPRINTF((2, "ACCESS LEVEL:=0x%x, obj=0x%lx\n",
|
||||
(int) obj.security, obj.id));
|
||||
data_len = 5;
|
||||
} else completition = (uint8)-result;
|
||||
@ -888,61 +961,52 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
obj.type = GET_BE16(p);
|
||||
strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2));
|
||||
upstr(obj.name);
|
||||
DPRINTF(("TODO:Keyed Verify PW from OBJECT='%s'\n",obj.name));
|
||||
if (0 == (result = find_obj_id(&obj, 0))) {
|
||||
/* TODO: check password !!!!!!! */
|
||||
;;
|
||||
}
|
||||
if (!result) {
|
||||
;;;
|
||||
} else
|
||||
completition = (uint8) -result;
|
||||
if (0 == (result = find_obj_id(&obj, 0)))
|
||||
result=nw_test_passwd(obj.id, c->crypt_key, rdata);
|
||||
if (result < 0) completition = (uint8) -result;
|
||||
XDPRINTF((2, "Keyed Verify PW from OBJECT='%s', result=%d\n",
|
||||
obj.name, result));
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 0x4b : { /* keyed change pasword */
|
||||
uint8 *p = rdata+sizeof(c->crypt_key);
|
||||
NETOBJ obj;
|
||||
int result;
|
||||
uint8 *pw;
|
||||
int pw_len;
|
||||
obj.type = GET_BE16(p);
|
||||
p+=2;
|
||||
strmaxcpy((char*)obj.name, (char*)(p+1), *p);
|
||||
upstr(obj.name);
|
||||
p += (*p+1); /* here is now password */
|
||||
DPRINTF(("TODO:Keyed Change PW from OBJECT='%s'\n",obj.name));
|
||||
if (0 == (result = find_obj_id(&obj, 0))) {
|
||||
/* TODO: check password !!!!!!! */
|
||||
;;
|
||||
}
|
||||
if (!result) {
|
||||
;;;
|
||||
/* completition = 0xff; (password not ok) */
|
||||
} else
|
||||
completition = 0xff; /* password not ok) */
|
||||
/* completition = (uint8) -result; */
|
||||
p += (*p+1); /* here is now password-type ?? 0x60,0x66 */
|
||||
|
||||
if (0 == (result = find_obj_id(&obj, 0)))
|
||||
/*
|
||||
result=nw_test_passwd(obj.id, c->crypt_key, rdata);
|
||||
if (result > -1)
|
||||
*/
|
||||
result=nw_set_enpasswd(obj.id, p+1);
|
||||
|
||||
if (result< 0) completition = (uint8) -result;
|
||||
DPRINTF(("Keyed Change PW from OBJECT='%s', result=0x%x\n",
|
||||
obj.name, result));
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 0x4c : { /* List Relations of an Object */
|
||||
|
||||
|
||||
} break;
|
||||
#endif
|
||||
|
||||
case 0x4c : { /* List Relations of an Object */
|
||||
DPRINTF(("TODO:List Relations of an Object\n"));
|
||||
completition=0xfb;
|
||||
} break;
|
||||
|
||||
case 0x64 : { /* Create Queue */
|
||||
/* !!!!!! TO DO */
|
||||
DPRINTF(("Create QUEUE ??\n"));
|
||||
DPRINTF(("TODO:Create QUEUE ??\n"));
|
||||
} break;
|
||||
|
||||
case 0x66 : { /* Read Queue Current Status */
|
||||
/* !!!!!! TO DO */
|
||||
NETOBJ obj;
|
||||
obj.id = GET_BE32(rdata);
|
||||
DPRINTF(("READ QUEUE STATUS von Q=0x%lx\n", obj.id));
|
||||
DPRINTF(("TODO:READ QUEUE STATUS von Q=0x%lx\n", obj.id));
|
||||
completition=0xd5; /* no Queue Job */
|
||||
}break;
|
||||
|
||||
@ -950,7 +1014,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
/* !!!!!! TO DO */
|
||||
NETOBJ obj;
|
||||
obj.id = GET_BE32(rdata);
|
||||
DPRINTF(("GET QUEUE JOB LIST von Q=0x%lx\n", obj.id));
|
||||
DPRINTF(("TODO:GET QUEUE JOB LIST von Q=0x%lx\n", obj.id));
|
||||
completition=0xd5; /* no Queue Job */
|
||||
}break;
|
||||
|
||||
@ -962,6 +1026,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
completition=0xd5; /* no Queue Job */
|
||||
}break;
|
||||
|
||||
case 0x68: /* creat queue job and file old */
|
||||
case 0x79: { /* creat queue job and file */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint8 *dir_name = rdata+4+280+1;
|
||||
@ -974,6 +1039,8 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0x69: /* close file and start queue old ?? */
|
||||
case 0x7f: { /* close file and start queue */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint8 *prc = rdata+4+4+1;
|
||||
@ -992,9 +1059,9 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
} break;
|
||||
|
||||
case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */
|
||||
char *company = "Mars";
|
||||
char *company = "Mars :-)";
|
||||
char *revision = "Version %d.%d";
|
||||
char *revision_date= "22-Nov-95";
|
||||
char *revision_date= "20-Dec-95";
|
||||
char *copyright = "(C)opyright Martin Stover";
|
||||
int k=strlen(company)+1;
|
||||
|
||||
@ -1036,7 +1103,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
CONNECTION *cc= &(connections[conn]);
|
||||
if (cc->object_id) { /* if logged */
|
||||
strmaxcpy(cc->message, msg, min(58, msglen));
|
||||
write_to_nwserv(0x8888, conn+1, NULL, 0);
|
||||
nwserv_handle_msg(conn+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1050,11 +1117,16 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
case 0xfd : /* Send Console Broadcast (new) */
|
||||
return(-1); /* nicht erkannt */
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0xd3 : { /* down File Server */
|
||||
if (c->object_id == 1) { /* only SUPERVISOR */
|
||||
/* inform nwserv */
|
||||
nwserv_down_server();
|
||||
} else completition = 0xff;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default : return(-1); /* not known here */
|
||||
} /* switch */
|
||||
} else return(-1); /* not kwown here */
|
||||
@ -1067,7 +1139,7 @@ static int handle_fxx(CONNECTION *c, int gelen, int func)
|
||||
ncpresponse->connect_status = connect_status;
|
||||
data_len=write(c->fd, (char*)ncpresponse,
|
||||
sizeof(NCPRESPONSE) + data_len);
|
||||
DPRINTF(("0x%x 0x%x compl:0x%x, write to %d, anz = %d\n",
|
||||
XDPRINTF((2, "0x%x 0x%x compl:0x%x, write to %d, anz = %d\n",
|
||||
func, (int)ufunc, (int) completition, c->fd, data_len));
|
||||
return(0); /* ok */
|
||||
}
|
||||
@ -1103,6 +1175,7 @@ static void sig_child(int isig)
|
||||
int k=-1;
|
||||
int status;
|
||||
int pid=wait(&status);
|
||||
if (pid > -1) {
|
||||
while (++k < anz_connect) {
|
||||
CONNECTION *c = &connections[k];
|
||||
if (c->pid == pid) {
|
||||
@ -1110,21 +1183,37 @@ static void sig_child(int isig)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
signal(SIGCHLD, sig_child);
|
||||
}
|
||||
|
||||
static int fl_got_hup=0;
|
||||
static void sig_hup(int rsig)
|
||||
static void close_all(void)
|
||||
{
|
||||
int k=0;
|
||||
while (k++ < anz_connect) clear_connection(k);
|
||||
if (ncp_fd > -1) {
|
||||
t_unbind(ncp_fd);
|
||||
t_close(ncp_fd);
|
||||
XDPRINTF((2, "LEAVE ncpserv\n"));
|
||||
ncp_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_quit(int isig)
|
||||
{
|
||||
close_all();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static void set_sig(void)
|
||||
{
|
||||
signal(SIGTERM, sig_quit);
|
||||
signal(SIGQUIT, sig_quit);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGCHLD, sig_child);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
fl_got_hup++;
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
void set_sig(void)
|
||||
{
|
||||
signal(SIGCHLD, sig_child);
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
static void handle_bind_calls(uint8 *p)
|
||||
@ -1160,13 +1249,14 @@ static void handle_bind_calls(uint8 *p)
|
||||
}
|
||||
|
||||
static int handle_ctrl(void)
|
||||
/* reads stdin pipe */
|
||||
{
|
||||
int what;
|
||||
int conn;
|
||||
int result = 0;
|
||||
int data_len = read(0, (char*)&what, sizeof(what));
|
||||
if (data_len == sizeof(what)) {
|
||||
DPRINTF(("NCPSERV:GOT CTRL what=0x%x\n", what));
|
||||
XDPRINTF((2, "NCPSERV:GOT CTRL what=0x%x\n", what));
|
||||
switch (what) {
|
||||
case 0x5555 : /* clear_connection */
|
||||
data_len = read(0, (char*)&conn, sizeof(conn));
|
||||
@ -1186,50 +1276,39 @@ static int handle_ctrl(void)
|
||||
break;
|
||||
|
||||
case 0xeeee:
|
||||
get_ini_debug(2);
|
||||
get_ini_debug(NCPSERV);
|
||||
nw_fill_standard(NULL, NULL);
|
||||
break;
|
||||
|
||||
case 0xffff : /* server down */
|
||||
data_len = read(0, (char*)&conn, sizeof(conn));
|
||||
if (sizeof(int) == data_len && conn == what)
|
||||
sent_down_message();
|
||||
break;
|
||||
|
||||
default : break;
|
||||
} /* switch */
|
||||
result++;
|
||||
} else DPRINTF(("NCPSERV:GOT CTRL size=%d\n", data_len));
|
||||
} else XDPRINTF((2, "NCPSERV:GOT CTRL size=%d\n", data_len));
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void handle_hup(void)
|
||||
{
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
XDPRINTF((2, "HANDLE_HUP_BEGIN\n"));
|
||||
fl_got_hup = handle_ctrl();
|
||||
XDPRINTF((2, "HANDLE_HUP_END fl_got_hup=%d\n", fl_got_hup));
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int result;
|
||||
int type;
|
||||
|
||||
if (argc != 8) {
|
||||
fprintf(stderr, "usage ncpserv address nwname GID UID debug1 debug2 debug3\n");
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage ncpserv address nwname\n");
|
||||
exit(1);
|
||||
}
|
||||
init_tools(NCPSERV);
|
||||
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);
|
||||
|
||||
sscanf(argv[3], "%d", &conn_gid);
|
||||
sscanf(argv[4], "%d", &conn_uid);
|
||||
|
||||
sscanf(argv[5], "%d", &nw_debug);
|
||||
sscanf(argv[6], "%d", &nwconn_debug);
|
||||
sscanf(argv[7], "%d", &ipxdebug);
|
||||
|
||||
#ifdef LINUX
|
||||
set_emu_tli(ipxdebug);
|
||||
set_emu_tli();
|
||||
#endif
|
||||
|
||||
if (open_ncp_socket()) exit(1);
|
||||
ud.opt.len = sizeof(ipx_pack_typ);
|
||||
ud.opt.maxlen = sizeof(ipx_pack_typ);
|
||||
@ -1243,12 +1322,27 @@ int main(int argc, char *argv[])
|
||||
ud.udata.maxlen = IPX_MAX_DATA;
|
||||
ud.udata.buf = (char*)&ipx_in_data;
|
||||
set_sig();
|
||||
fcntl(0, F_SETFL, O_NONBLOCK); /* non blocking input pipe */
|
||||
|
||||
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) {
|
||||
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,"POLL %d\n", 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;
|
||||
if (fl_got_hup) handle_hup();
|
||||
XDPRINTF((10, "NCPSERV-LOOP von %s\n", visable_ipx_adr(&from_addr)));
|
||||
if ((type = GET_BE16(ncprequest->type)) == 0x2222 || type == 0x5555) {
|
||||
int connection = (int)ncprequest->connection;
|
||||
@ -1264,15 +1358,14 @@ int main(int argc, char *argv[])
|
||||
c->last_access = akttime;
|
||||
|
||||
if (diff_time > 50) /* after max. 50 seconds */
|
||||
write_to_nwserv(0x4444, connection, NULL,0);
|
||||
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);
|
||||
DPRINTF(("Send Request being serviced to connection:%d\n", connection));
|
||||
XDPRINTF((2, "Send Request being serviced to connection:%d\n", connection));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1294,7 +1387,7 @@ int main(int argc, char *argv[])
|
||||
c->sequence = ncprequest->sequence; /* save last sequence */
|
||||
c->retry = 0;
|
||||
continue;
|
||||
} else { /* 0x5555 */
|
||||
} else { /* 0x5555, conection beenden */
|
||||
if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence) {
|
||||
clear_connection(ncprequest->connection);
|
||||
ncp_response(0x3333,
|
||||
@ -1309,15 +1402,15 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
/* here someting is wrong */
|
||||
XDPRINTF((0, "GOT 0x%x connection=%d of %d conns not OK in NCPSERV\n",
|
||||
XDPRINTF((1, "GOT 0x%x connection=%d of %d conns not OK in NCPSERV\n",
|
||||
type, ncprequest->connection, anz_connect));
|
||||
ncp_response(0x3333, ncprequest->sequence,
|
||||
ncprequest->connection,
|
||||
0, 0xf9, 0, 0);
|
||||
} else if (type == 0x1111) {
|
||||
/* GIVE CONNECTION Nr connection */
|
||||
int connection = find_get_conn_nr(&from_addr);
|
||||
DPRINTF(("GIVE CONNECTION NR=%d in NCPSERV\n", connection));
|
||||
int connection = (server_goes_down) ? 0 : find_get_conn_nr(&from_addr);
|
||||
XDPRINTF((2, "GIVE CONNECTION NR=%d in NCPSERV\n", connection));
|
||||
if (connection) {
|
||||
CONNECTION *c = &(connections[connection-1]);
|
||||
int anz;
|
||||
@ -1331,18 +1424,27 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
int connection = (int)ncprequest->connection;
|
||||
int sequence = (int)ncprequest->sequence;
|
||||
XDPRINTF((0, "UNKNOWN TYPE: 0x%x\n", type));
|
||||
XDPRINTF((1, "NCPSERV:Got UNKNOWN TYPE: 0x%x\n", type));
|
||||
ncp_response(0x3333, sequence, connection,
|
||||
1, 0xfb, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (p->fd==0) { /* fd_ncpserv_in */
|
||||
XDPRINTF((2,"POLL %d, fh=%d\n", p->revents, p->fd));
|
||||
if (p->revents & ~POLLIN)
|
||||
errorp(0, "STREAM error", "revents=0x%x", p->revents );
|
||||
else handle_ctrl();
|
||||
}
|
||||
if (! --anz_poll) break;
|
||||
} /* if */
|
||||
p++;
|
||||
} /* while */
|
||||
} else {
|
||||
if (fl_got_hup) handle_hup();
|
||||
else t_error("NCPSERV t_rcvudata");
|
||||
XDPRINTF((3,"NCPSERV:POLLING ...\n"));
|
||||
}
|
||||
}
|
||||
printf("LEAVE ncpserv\n");
|
||||
t_unbind(ncp_fd);
|
||||
t_close(ncp_fd);
|
||||
close_all();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
66
net.h
66
net.h
@ -48,6 +48,8 @@
|
||||
# include "emutli.h" /* TLI-EMULATION */
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
@ -162,7 +164,7 @@ typedef union {
|
||||
*
|
||||
*/
|
||||
} diaresp;
|
||||
struct S_NCPRESPONSE {
|
||||
struct S_NCPRESPONSE { /* size = 8 */
|
||||
uint8 type[2]; /* 0x3333 */
|
||||
uint8 sequence;
|
||||
uint8 connection; /* low connection */
|
||||
@ -171,7 +173,7 @@ typedef union {
|
||||
uint8 completition; /* bzw. ERROR CODE */
|
||||
uint8 connect_status;
|
||||
} ncpresponse;
|
||||
struct S_NCPREQUEST {
|
||||
struct S_NCPREQUEST { /* size = 7 */
|
||||
uint8 type[2]; /* 0x1111 od 0x2222 */
|
||||
uint8 sequence;
|
||||
uint8 connection; /* low connection */
|
||||
@ -229,6 +231,11 @@ typedef struct S_NCPREQUEST NCPREQUEST;
|
||||
# define MAX_NW_VOLS 10
|
||||
#endif
|
||||
|
||||
#ifndef MAX_NET_DEVICES
|
||||
# define MAX_NET_DEVICES 5
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FILENAME_NW_INI
|
||||
# define FILENAME_NW_INI "./nw.ini" /* location of ini (conf) file */
|
||||
#endif
|
||||
@ -271,8 +278,8 @@ typedef struct {
|
||||
uint8 client_id[4];
|
||||
|
||||
uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */
|
||||
uint8 target_execute_time[6]; /* alles 0xff */
|
||||
uint8 job_entry_time[6]; /* ?? alles 0 */
|
||||
uint8 target_execute_time[6]; /* all 0xff */
|
||||
uint8 job_entry_time[6]; /* all zero */
|
||||
uint8 job_id[4]; /* ?? alles 0 HI-LOW */
|
||||
uint8 job_typ[2]; /* z.B. Printform HI-LOW */
|
||||
uint8 job_position[2]; /* ?? alles 0 low-high ? */
|
||||
@ -292,21 +299,48 @@ typedef struct {
|
||||
uint8 client_area[152];
|
||||
} QUEUE_JOB;
|
||||
|
||||
typedef struct {
|
||||
uint8 client_connection;
|
||||
uint8 client_task;
|
||||
uint8 client_id[4];
|
||||
uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */
|
||||
uint8 target_execute_time[6]; /* all 0xff */
|
||||
uint8 job_entry_time[6]; /* all zero */
|
||||
uint8 job_id[2]; /* ?? alles 0 HI-LOW */
|
||||
uint8 job_typ[2]; /* z.B. Printform HI-LOW */
|
||||
uint8 job_position; /* zero */
|
||||
uint8 job_control_flags; /* z.B 0x10 */
|
||||
/* 0x80 operator hold flag */
|
||||
/* 0x40 user hold flag */
|
||||
/* 0x20 entry open flag */
|
||||
/* 0x10 service restart flag */
|
||||
/* 0x08 autostart flag */
|
||||
|
||||
uint8 job_file_name[14]; /* len + DOS filename */
|
||||
uint8 job_file_handle[6];
|
||||
uint8 server_station;
|
||||
uint8 server_task;
|
||||
uint8 server_id[4];
|
||||
uint8 job_bez[50]; /* "LPT1 Catch" */
|
||||
uint8 client_area[152];
|
||||
} QUEUE_JOB_OLD; /* before 3.11 */
|
||||
|
||||
typedef struct {
|
||||
uint8 version; /* normal 0x0 */
|
||||
uint8 tabsize; /* normal 0x8 */
|
||||
uint8 anz_copies[2]; /* Anzahl Copien HI-LOW */
|
||||
uint8 print_flags[2]; /* z.B fuer Banner */
|
||||
uint8 max_lines[2];
|
||||
uint8 max_chars[2];
|
||||
uint8 anz_copies[2]; /* copies 0x0, 0x01 */
|
||||
uint8 print_flags[2]; /* 0x0, 0xc0 z.B. with banner */
|
||||
uint8 max_lines[2]; /* 0x0, 0x42 */
|
||||
uint8 max_chars[2]; /* 0x0, 0x84 */
|
||||
uint8 form_name[16]; /* "UNKNOWN" */
|
||||
uint8 reserved[6];
|
||||
uint8 banner_user_name[13]; /* Username */
|
||||
uint8 bannner_file_name[13];
|
||||
uint8 bannner_header_file_name[14];
|
||||
uint8 file_path_name[80];
|
||||
uint8 reserved[6]; /* all zero */
|
||||
uint8 banner_user_name[13]; /* "SUPERVISOR" */
|
||||
uint8 bannner_file_name[13]; /* "LST:" */
|
||||
uint8 bannner_header_file_name[14]; /* all zero */
|
||||
uint8 file_path_name[80]; /* all zero */
|
||||
} QUEUE_PRINT_AREA;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8 volume;
|
||||
uint8 base[4]; /* Base or Handle */
|
||||
@ -387,17 +421,13 @@ extern int nw_get_volume_name(int volnr, uint8 *volname);
|
||||
|
||||
|
||||
|
||||
extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len);
|
||||
extern int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus);
|
||||
|
||||
extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit);
|
||||
extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len,
|
||||
uint8 *subnr, uint8 *subname,
|
||||
uint8 *subdatetime, uint8 *owner);
|
||||
|
||||
|
||||
extern int nw_generate_dir_path(uint8 *nwpathstruct,
|
||||
uint8 *ns_dir_base, uint8 *dos_dir_base);
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
extern int nw_get_fs_usage(char *volname, struct fs_usage *fsu);
|
||||
|
28
net1.c
28
net1.c
@ -1,4 +1,4 @@
|
||||
/* net1.c, 11-Sep-95 */
|
||||
/* net1.c, 10-Dec-95 */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -22,9 +22,9 @@
|
||||
#if HAVE_TLI
|
||||
void print_t_info(struct t_info *t)
|
||||
{
|
||||
DPRINTF(("T_INFO:addr %ld, options %ld, tsdu %ld, etsdu %ld\n",
|
||||
XDPRINTF((2,"T_INFO:addr %ld, options %ld, tsdu %ld, etsdu %ld\n",
|
||||
t->addr, t->options,t->tsdu, t->etsdu));
|
||||
DPRINTF(("connect %ld, discon %ld, servtype %ld\n",
|
||||
XDPRINTF((2,"connect %ld, discon %ld, servtype %ld\n",
|
||||
t->connect, t->discon,t->servtype));
|
||||
#if 0
|
||||
struct t_info {
|
||||
@ -42,16 +42,20 @@ void print_t_info(struct t_info *t)
|
||||
char *visable_ipx_adr(ipxAddr_t *p)
|
||||
{
|
||||
static char str[200];
|
||||
if (p)
|
||||
sprintf(str,"net=%x:%x:%x:%x, node=%x:%x:%x:%x:%x:%x, sock=%02x:%02x",
|
||||
(int)p->net[0], (int)p->net[1], (int)p->net[2], (int)p->net[3],
|
||||
(int)p->node[0], (int)p->node[1], (int)p->node[2], (int)p->node[3],
|
||||
(int)p->node[4], (int)p->node[5], (int)p->sock[0], (int)p->sock[1]);
|
||||
else
|
||||
strcpy(str, "net=UNKOWN(NULLPOINTER)");
|
||||
|
||||
return(str);
|
||||
}
|
||||
|
||||
void print_ipx_addr(ipxAddr_t *p)
|
||||
{
|
||||
DPRINTF(("%s\n", visable_ipx_adr(p)));
|
||||
XDPRINTF((2,"%s\n", visable_ipx_adr(p)));
|
||||
}
|
||||
|
||||
void print_ud_data(struct t_unitdata *ud)
|
||||
@ -59,21 +63,21 @@ void print_ud_data(struct t_unitdata *ud)
|
||||
int packet_typ = *(int*)(ud->opt.buf);
|
||||
int data_len = ud->udata.len;
|
||||
IPX_DATA *ipxdata = (IPX_DATA *)(ud->udata.buf);
|
||||
DPRINTF(("DATA-LEN %d, PACKET-TYPE %d von:",
|
||||
XDPRINTF((2,"DATA-LEN %d, PACKET-TYPE %d von:",
|
||||
data_len, packet_typ));
|
||||
/* hierin steht nun Addresse u. Node des Senders */
|
||||
print_ipx_addr((ipxAddr_t *)(ud->addr.buf));
|
||||
if (packet_typ == PACKT_CORE) {
|
||||
DPRINTF(("Query Type 0x%x, Server Type 0x%xd\n",
|
||||
XDPRINTF((2,"Query Type 0x%x, Server Type 0x%xd\n",
|
||||
GET_BE16(ipxdata->sqp.query_type),
|
||||
GET_BE16(ipxdata->sqp.server_type)));
|
||||
} else if (data_len > sizeof(SIP)){
|
||||
SAP *sap = &(ipxdata->sap);
|
||||
SAPS *saps = &(ipxdata->sap.saps);
|
||||
int sap_operation = GET_BE16(sap->sap_operation);
|
||||
DPRINTF(("SAP-OPERATION %d\n", sap_operation));
|
||||
XDPRINTF((2,"SAP-OPERATION %d\n", sap_operation));
|
||||
while (data_len >= sizeof(SAPS)){
|
||||
DPRINTF(("Name:%s:, typ:0x%x\n",saps->server_name,
|
||||
XDPRINTF((2,"Name:%s:, typ:0x%x\n",saps->server_name,
|
||||
GET_BE16(saps->server_type)));
|
||||
print_ipx_addr(&(saps->server_adr));
|
||||
saps++;
|
||||
@ -89,7 +93,7 @@ void print_ipx_data(IPX_DATA *p)
|
||||
|
||||
void print_sip_data(SIP *sip)
|
||||
{
|
||||
DPRINTF(("Name:%s:,response_type:0x%x,server_typ:0x%x\n",sip->server_name,
|
||||
XDPRINTF((2,"Name:%s:,response_type:0x%x,server_typ:0x%x\n",sip->server_name,
|
||||
GET_BE16(sip->response_type), GET_BE16(sip->server_type)));
|
||||
print_ipx_addr(&(sip->server_adr));
|
||||
}
|
||||
@ -151,10 +155,10 @@ int send_ipx_data(int fd, int pack_typ,
|
||||
ud.udata.len = data_len;
|
||||
ud.udata.maxlen = data_len;
|
||||
ud.addr.buf = (char*)to_addr;
|
||||
if (comment != NULL) DPRINTF(("%s TO: ", comment));
|
||||
if (nw_debug)print_ipx_addr(to_addr);
|
||||
if (comment != NULL) XDPRINTF((2,"%s TO: ", comment));
|
||||
if (nw_debug > 1) print_ipx_addr(to_addr);
|
||||
if (t_sndudata(fd, &ud) < 0){
|
||||
t_error("t_sndudata !OK");
|
||||
if (nw_debug > 1) t_error("t_sndudata !OK");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
|
409
nwconn.c
409
nwconn.c
@ -1,4 +1,4 @@
|
||||
/* nwconn.c 20-Nov-95 */
|
||||
/* nwconn.c 04-Dec-95 */
|
||||
/* one process / connection */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
@ -19,10 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "net.h"
|
||||
static int default_uid=-1;
|
||||
static int default_gid=-1;
|
||||
|
||||
static int ipxdebug=0;
|
||||
|
||||
static int father_pid = -1;
|
||||
static ipxAddr_t from_addr;
|
||||
@ -48,7 +44,7 @@ static int open_ipx_socket()
|
||||
struct t_bind bind;
|
||||
ipx_fd=t_open("/dev/ipx", O_RDWR, NULL);
|
||||
if (ipx_fd < 0) {
|
||||
t_error("t_open !Ok");
|
||||
if (nw_debug) t_error("t_open !Ok");
|
||||
return(-1);
|
||||
}
|
||||
U16_TO_BE16(0, my_addr.sock); /* actual write socket */
|
||||
@ -57,21 +53,15 @@ static int open_ipx_socket()
|
||||
bind.addr.buf = (char*)&my_addr;
|
||||
bind.qlen = 0; /* allways */
|
||||
if (t_bind(ipx_fd, &bind, &bind) < 0){
|
||||
t_error("t_bind !OK");
|
||||
if (nw_debug) t_error("t_bind !OK");
|
||||
close(ipx_fd);
|
||||
return(-1);
|
||||
}
|
||||
DPRINTF(("NWCONN OpenSocket: %s\n",
|
||||
XDPRINTF((2, "NWCONN OpenSocket: %s\n",
|
||||
visable_ipx_adr((ipxAddr_t *) bind.addr.buf)));
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void set_default_guid(void)
|
||||
{
|
||||
setgid(default_gid);
|
||||
setuid(default_uid);
|
||||
}
|
||||
|
||||
static int ncp_response(int sequence,
|
||||
int completition, int data_len)
|
||||
|
||||
@ -79,13 +69,13 @@ static int ncp_response(int sequence,
|
||||
ncpresponse->sequence = (uint8) sequence;
|
||||
ncpresponse->completition = (uint8) completition;
|
||||
last_sequence = sequence;
|
||||
DPRINTF(("NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x TO %s\n",
|
||||
XDPRINTF((2,"NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x TO %s\n",
|
||||
(int)ncpresponse->sequence, (int) ncpresponse->connection, (int)completition,
|
||||
visable_ipx_adr((ipxAddr_t *) ud.addr.buf)));
|
||||
|
||||
ud.udata.len = ud.udata.maxlen = sizeof(NCPRESPONSE) + data_len;
|
||||
if (t_sndudata(ipx_fd, &ud) < 0){
|
||||
t_error("t_sndudata in NWCONN !OK");
|
||||
if (nw_debug) t_error("t_sndudata in NWCONN !OK");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
@ -106,12 +96,13 @@ static void handle_ncp_serv()
|
||||
|
||||
if (last_sequence == sequence && ncp_type != 0x1111){ /* send the same again */
|
||||
if (t_sndudata(ipx_fd, &ud) < 0){
|
||||
t_error("t_sndudata !OK");
|
||||
if (nw_debug) t_error("t_sndudata !OK");
|
||||
}
|
||||
DPRINTF(("Sequence %d is written twice\n", sequence));
|
||||
XDPRINTF((2,"Sequence %d is written twice\n", sequence));
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!nw_debug && (
|
||||
/*
|
||||
function == 0x43 ||
|
||||
@ -121,30 +112,30 @@ static void handle_ncp_serv()
|
||||
*/
|
||||
function == 0x11
|
||||
) ) nw_debug=1;
|
||||
|
||||
#endif
|
||||
|
||||
if (nw_debug){
|
||||
int j = requestlen;
|
||||
if (nw_debug == 1
|
||||
if (nw_debug < 10
|
||||
&& (function==0x48 || function == 0x49)) /* read or write */
|
||||
nw_debug=0;
|
||||
if (nw_debug == 2
|
||||
if (nw_debug < 15
|
||||
&& (function==0x48)) /* read */
|
||||
nw_debug=0;
|
||||
|
||||
if (nw_debug){
|
||||
if (nw_debug > 1){
|
||||
do_druck=2;
|
||||
DPRINTF(("NCP REQUEST:type:0x%x, seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||||
XDPRINTF((2,"NCP REQUEST:type:0x%x, seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||||
ncp_type, sequence, task, reserved, function));
|
||||
if (j > 0){
|
||||
uint8 *p=requestdata;
|
||||
DPRINTF(("len %d, DATA:", j));
|
||||
XDPRINTF((2,"len %d, DATA:", j));
|
||||
while (j--) {
|
||||
int c = *p++;
|
||||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||||
else DPRINTF((",0x%x", c));
|
||||
if (c > 32 && c < 127) XDPRINTF((2,",\'%c\'", (char) c));
|
||||
else XDPRINTF((2,",0x%x", c));
|
||||
}
|
||||
DPRINTF(("\n"));
|
||||
XDPRINTF((2,"\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,9 +203,7 @@ static void handle_ncp_serv()
|
||||
/****** * SetDirektoryHandle *************/
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen;
|
||||
uint8 type; /* 0x0 */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 target_dir_handle; /* Verzeichnis Handle zu „ndern */
|
||||
uint8 source_dir_handle; /* Verzeichnis Handle */
|
||||
uint8 pathlen;
|
||||
@ -231,9 +220,7 @@ static void handle_ncp_serv()
|
||||
/******** GetDirektoryPATH ***************/
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen; /* 0x2 */
|
||||
uint8 type; /* 0x1 */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
struct XDATA {
|
||||
@ -245,15 +232,13 @@ static void handle_ncp_serv()
|
||||
xdata->len = (uint8) result;
|
||||
data_len = result + 1;
|
||||
xdata->name[result] = '\0';
|
||||
DPRINTF(("GetDirektoryPATH=%s\n", xdata->name));
|
||||
XDPRINTF((2,"GetDirektoryPATH=%s\n", xdata->name));
|
||||
} else completition = (uint8)-result;
|
||||
} else if (2 == *p){ /* Scan Direktory Information */
|
||||
/******** Scan Dir Info ****************/
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen; /* */
|
||||
uint8 type; /* 0x2 */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 sub_dir_nmbr[2]; /* HI LOW */
|
||||
uint8 len; /* kann auch 0 sein */
|
||||
@ -276,18 +261,21 @@ static void handle_ncp_serv()
|
||||
if (result > -1){
|
||||
xdata->max_right_mask = (uint8)result;
|
||||
data_len = sizeof(struct XDATA);
|
||||
DPRINTF(("Scan Dir Info max_right_mask=%d\n", (int)result));
|
||||
XDPRINTF((2,"Scan Dir Info max_right_mask=%d\n", (int)result));
|
||||
} else completition = (uint8)-result;
|
||||
} else if (*p == 0x3){ /* Get Direktory Rights */
|
||||
/******** Get Eff Dir Rights ****************/
|
||||
struct XDATA {
|
||||
uint8 eff_right_mask; /* Effektive Right to Dir, old! */
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
int result = nw_get_eff_dir_rights((int)*(p+1), p+3, (int)*(p+2));
|
||||
int result = nw_get_eff_dir_rights(
|
||||
(int)*(p+1),
|
||||
p+3,
|
||||
(int)*(p+2), 0);
|
||||
if (result > -1) {
|
||||
xdata->eff_right_mask = (uint8) result;
|
||||
data_len = 1;
|
||||
DPRINTF(("Get eff Dir Rights=%d\n", (int)result));
|
||||
XDPRINTF((2,"Got eff Dir Rights=%d\n", (int)result));
|
||||
} else completition = (uint8) -result;
|
||||
} else if (*p == 0x4){ /* Modify Max Right MAsk */
|
||||
/******** MODIFY MAX RIGHT MASK ****************/
|
||||
@ -336,9 +324,7 @@ static void handle_ncp_serv()
|
||||
/******** GetDirektoryPATH ***************/
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen;
|
||||
uint8 type;
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||||
uint8 trustee_right_mask;
|
||||
@ -402,7 +388,7 @@ static void handle_ncp_serv()
|
||||
U16_TO_BE16(0, xdata->removable);
|
||||
}
|
||||
data_len = sizeof(struct XDATA);
|
||||
DPRINTF(("GIVE VOLUME INFO von :%s:\n", xdata->name));
|
||||
XDPRINTF((2,"GIVE VOLUME INFO von :%s:\n", xdata->name));
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
@ -410,9 +396,7 @@ static void handle_ncp_serv()
|
||||
} else if (*p == 0x19){ /* Set Directory Information */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen;
|
||||
uint8 sub_func;
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||||
uint8 trustee_right_mask;
|
||||
@ -424,9 +408,7 @@ static void handle_ncp_serv()
|
||||
} else if (*p == 0x1a){ /* Get Pathname of A Volume Dir Pair */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen;
|
||||
uint8 sub_func;
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 volume;
|
||||
uint8 dir_entry[2];
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
@ -434,67 +416,95 @@ static void handle_ncp_serv()
|
||||
uint8 pathlen;
|
||||
uint8 pathname;
|
||||
} *xdata = (struct XDATA*)responsedata;
|
||||
completition = 0xfb; /* !!!!! Machen !!!! */
|
||||
} else if (*p == 0x1e){ /* liefert Trustees ?? */
|
||||
/* des Dir_handles + PATH */
|
||||
completition = 0xfb; /* !!!!! TODO !!!! */
|
||||
} else if (*p == 0x1e){
|
||||
/* SCAN a Directory */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen; /* 0x2 */
|
||||
uint8 type; /* 0x1e */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 attrib; /* Attrib ?? 0x6 */
|
||||
uint8 reserve1[4]; /* alles 0xff */
|
||||
uint8 attrib; /* Search Attrib z.B. 0x6 */
|
||||
uint8 searchsequence[4]; /* 32 bit */
|
||||
uint8 len;
|
||||
uint8 data[2];
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
NW_FILE_INFO f;
|
||||
int result = nw_scan_a_directory(
|
||||
responsedata,
|
||||
input->dir_handle,
|
||||
input->data,
|
||||
input->len,
|
||||
input->attrib,
|
||||
GET_BE32(input->searchsequence));
|
||||
|
||||
if (result > -1) data_len = result;
|
||||
else completition = (uint8) (-result);
|
||||
} else if (*p == 0x1f){
|
||||
/* SCAN a root dir ???? */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 dont_know1; /* ???? 0xc0 */
|
||||
uint8 dont_know2; /* ???? 0xfa */
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
int result = nw_scan_a_root_dir(
|
||||
responsedata,
|
||||
input->dir_handle);
|
||||
if (result > -1) data_len = result;
|
||||
else completition = (uint8) (-result);
|
||||
} else if (*p == 0x20){ /* scan volume user disk restrictions */
|
||||
uint8 volnr = *(p+1);
|
||||
uint32 sequenz = GET_BE32(p+2);
|
||||
struct XDATA {
|
||||
uint8 unknown[15];
|
||||
uint8 namlen;
|
||||
uint8 name[14];
|
||||
} *xdata = (struct XDATA*)responsedata;
|
||||
int len=input->len;
|
||||
int searchsequence = nw_search( (uint8*)
|
||||
&(f),
|
||||
(int)input->dir_handle,
|
||||
MAX_U16,
|
||||
(int) input->attrib,
|
||||
input->data, len);
|
||||
if (searchsequence > -1){
|
||||
memset(xdata, 0, 132);
|
||||
xdata->namlen = min(14, strlen(f.name));
|
||||
memcpy(xdata->name, f.name, xdata->namlen);
|
||||
} else completition = (uint8) - searchsequence;
|
||||
} else if (*p == 0x20){ /* testet ??*/
|
||||
struct XDATA {
|
||||
uint8 res1; /* 0x0 */
|
||||
uint8 entries; /* 0x0 */
|
||||
/*--- per entry (max.entries = 12) ----*/
|
||||
uint8 id[4];
|
||||
uint8 restriction[4];
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
xdata->res1 = 0x0;
|
||||
data_len = 1;
|
||||
xdata->entries = 0x0;
|
||||
data_len = (8 * xdata->entries) + 1;
|
||||
} else if (*p == 0x21) {
|
||||
/* change Vol restrictions for Obj */
|
||||
uint8 volnr = *(p+1);
|
||||
uint32 id = GET_BE32(p+2);
|
||||
uint32 blocks = GET_BE32(p+6);
|
||||
DPRINTF(("Change vol restriction vol=%d, id=0x%lx, Blocks=0x%lx",
|
||||
XDPRINTF((2,"TODO:Change vol restriction vol=%d, id=0x%lx, Blocks=0x%lx",
|
||||
(int)volnr, id, blocks));
|
||||
} else if (*p == 0x22) {
|
||||
/* remove Vol restrictions for Obj */
|
||||
uint8 volnr = *(p+1);
|
||||
uint32 id = GET_BE32(p+2);
|
||||
DPRINTF(("Renmove vol restriction vol=%d, id=0x%lx",
|
||||
XDPRINTF((2,"Renmove vol restriction vol=%d, id=0x%lx",
|
||||
(int)volnr, id));
|
||||
|
||||
} else if (*p == 0x25){ /* setting FILE INFO ??*/
|
||||
/* TODO !!!!!!!!!!!!!!!!!!!! */
|
||||
do_druck++;
|
||||
} else if (*p == 0x27){ /* Add Trustees to DIR ?? */
|
||||
} else if (*p == 0x26) { /* Scan file or Dir for ext trustees */
|
||||
int sequenz = (int)*(p+2); /* trustee sequenz */
|
||||
struct XDATA {
|
||||
uint8 entries;
|
||||
uint8 ids[80]; /* 20 id's */
|
||||
uint8 trustees[40]; /* 20 trustees's */
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
int result = nw_get_eff_dir_rights(
|
||||
(int)*(p+1),
|
||||
p+4,
|
||||
(int)*(p+3), 1);
|
||||
if (result > -1){
|
||||
if (!sequenz) {
|
||||
memset(xdata, 0, sizeof(struct XDATA));
|
||||
xdata->entries=1;
|
||||
U32_TO_BE32(1, xdata->ids); /* SUPERVISOR */
|
||||
xdata->trustees[1] = 0x1; /* Supervisory */
|
||||
xdata->trustees[0] = 0xff; /* all low */
|
||||
data_len = sizeof(struct XDATA);
|
||||
} else completition = 0x9c; /* no more trustees */
|
||||
} else completition = (uint8) (-result);
|
||||
} else if (*p == 0x27) { /* Add Trustees to DIR ?? */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 filler; /* 0x0 */
|
||||
uint8 datalen; /* 0x2 */
|
||||
uint8 type; /* 0x27 */
|
||||
uint8 div[3]; /* 0x0, dlen, typ */
|
||||
uint8 dir_handle; /* Verzeichnis Handle */
|
||||
uint8 trustee_id[4]; /* Trustee Object ID */
|
||||
uint8 trustee_right_mask;
|
||||
@ -511,39 +521,25 @@ static void handle_ncp_serv()
|
||||
struct XDATA {
|
||||
uint8 weisnicht[8]; /* ?????? */
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
DPRINTF(("Get vol restriction vol=%d, id=0x%lx",
|
||||
XDPRINTF((2,"Get vol restriction vol=%d, id=0x%lx",
|
||||
(int)volnr, id));
|
||||
memset(xdata, 0, sizeof(struct XDATA));
|
||||
data_len=sizeof(struct XDATA);
|
||||
} else if (*p == 0x2a){ /* Get Eff. Dir Rights ??*/
|
||||
/* from Dir_handles + PATH */
|
||||
} else if (*p == 0x2a){
|
||||
/* Get Eff. Rights of DIR's and Files ??*/
|
||||
struct XDATA {
|
||||
uint8 eff_rights; /* Effektive Right to Dir */
|
||||
uint8 unkwown_data; /* 0x1 */
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
NW_DIR_INFO d;
|
||||
int len=(int)*(p+2);
|
||||
int searchsequence;
|
||||
if (len)
|
||||
searchsequence = nw_search((uint8*)&(d),
|
||||
(int)*(p+1), /* dir_handle */
|
||||
MAX_U16,
|
||||
(int) 0x10, /* only dirs ?? */
|
||||
p+3, /* path */
|
||||
len); /* pathlen */
|
||||
else {
|
||||
searchsequence = nw_get_eff_dir_rights(
|
||||
int result = nw_get_eff_dir_rights(
|
||||
(int)*(p+1),
|
||||
p+3,
|
||||
len);
|
||||
if (searchsequence > -1)
|
||||
d.ext_attrib = searchsequence;
|
||||
}
|
||||
if (searchsequence > -1){
|
||||
xdata->eff_rights = d.ext_attrib;
|
||||
(int)*(p+2), 1);
|
||||
if (result > -1){
|
||||
xdata->eff_rights = (uint8)result;
|
||||
xdata->unkwown_data = 0x1;
|
||||
data_len = sizeof(struct XDATA);
|
||||
} else completition = (uint8) - searchsequence;
|
||||
} else completition = (uint8) (-result);
|
||||
} else if (*p == 0x2c){
|
||||
/* Get Volume and Purge Information */
|
||||
/* new Call since V3.11 */
|
||||
@ -610,6 +606,8 @@ static void handle_ncp_serv()
|
||||
} else completition = (uint8) -result;
|
||||
} else if (*p == 0x2e){ /* RENAME DATEI */
|
||||
completition = 0xfb; /* TODO: !!! */
|
||||
} else if (*p == 0x2f){ /* ?????? */
|
||||
completition = 0xfb; /* TODO: !!! */
|
||||
} else completition = 0xfb; /* unkwown request */
|
||||
}
|
||||
break;
|
||||
@ -619,12 +617,24 @@ static void handle_ncp_serv()
|
||||
uint8 len = *(requestdata+1);
|
||||
uint8 ufunc = *(requestdata+2);
|
||||
switch (ufunc) {
|
||||
case 0x14:
|
||||
case 0x18: { /* ncpserv have change the structure */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 div[3]; /* 0, len + ufunc */
|
||||
uint8 align[2]; /* alignment ncpserv */
|
||||
int gid; /* ncpserv */
|
||||
int uid; /* ncpserv */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
set_guid(input->gid, input->uid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0f: { /* Scan File Information */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 div[3]; /* 0, len + ufunc */
|
||||
uint8 sequence[2]; /* z.B. 0xff, 0xff */
|
||||
|
||||
uint8 dir_handle;
|
||||
uint8 search_attrib; /* 0: NONE */
|
||||
/* 02: HIDDEN */
|
||||
@ -666,14 +676,15 @@ static void handle_ncp_serv()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x68: /* creat queue job and file old */
|
||||
case 0x79: { /* creat queue job and file */
|
||||
/* somme of this call is handled in ncpserv !! */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 packetlen[2]; /* low high */
|
||||
uint8 func; /* 0x79 */
|
||||
uint8 func; /* 0x79 or 0x68 */
|
||||
uint8 queue_id[4]; /* Queue ID */
|
||||
uint8 queue_job[280];
|
||||
uint8 queue_job[280]; /* oldsize is 256 */
|
||||
/* this is added by ncpserv */
|
||||
uint8 dir_nam_len; /* len of dirname */
|
||||
uint8 dir_name[1];
|
||||
@ -682,21 +693,24 @@ static void handle_ncp_serv()
|
||||
input->queue_id,
|
||||
input->queue_job,
|
||||
input->dir_name,
|
||||
(int)input->dir_nam_len);
|
||||
(int)input->dir_nam_len,
|
||||
(ufunc == 0x68) );
|
||||
if (!result) {
|
||||
data_len = 78;
|
||||
data_len = (ufunc == 0x68) ? 54 : 78;
|
||||
memcpy(responsedata, input->queue_job, data_len);
|
||||
} else completition= (uint8)-result;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x69: /* close file and start queue old ?? */
|
||||
case 0x7f: { /* close file and start queue */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 packetlen[2]; /* low high */
|
||||
uint8 func; /* 0x7f */
|
||||
uint8 func; /* 0x7f or 0x6f */
|
||||
uint8 queue_id[4]; /* Queue ID */
|
||||
uint8 job_id[4]; /* result from creat queue */
|
||||
/* if 0x69 then only 2 byte ! */
|
||||
/* this is added by ncpserv */
|
||||
uint8 prc_len; /* len of printcommand */
|
||||
uint8 prc[1]; /* printcommand */
|
||||
@ -710,13 +724,13 @@ static void handle_ncp_serv()
|
||||
break;
|
||||
|
||||
case 0xf3: { /* Map Direktory Number TO PATH */
|
||||
DPRINTF(("TODO: Map Direktory Number TO PATH\n"));
|
||||
XDPRINTF((1,"TODO: Map Direktory Number TO PATH\n"));
|
||||
completition = 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf4: { /* Map PATH TO Dir Entry */
|
||||
DPRINTF(("TODO: Map PATH TO Dir Entry\n"));
|
||||
XDPRINTF((1,"TODO: Map PATH TO Dir Entry\n"));
|
||||
completition = 0xff;
|
||||
}
|
||||
break;
|
||||
@ -766,11 +780,11 @@ static void handle_ncp_serv()
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 0x22 : /* div TTS Calls */
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0x22 : { /* div TTS Calls */
|
||||
int ufunc = (int) *requestdata;
|
||||
if (!ufunc) completition=0; /* TTS not availible */
|
||||
else completition=0xfb; /* request not known */
|
||||
} break;
|
||||
|
||||
case 0x3e : { /* FILE SEARCH INIT */
|
||||
/* returns dhandle for searchings */
|
||||
@ -805,7 +819,7 @@ static void handle_ncp_serv()
|
||||
uint8 ext_fhandle[2]; /* all zero */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
uint32 fhandle = GET_BE32(input->fhandle);
|
||||
DPRINTF(("TODO: COMMIT FILE:fhandle=%ld\n", fhandle));
|
||||
XDPRINTF((1,"TODO: COMMIT FILE:fhandle=%ld\n", fhandle));
|
||||
/* TODO */
|
||||
;
|
||||
} break;
|
||||
@ -824,10 +838,11 @@ static void handle_ncp_serv()
|
||||
6 Both,
|
||||
* 0x10 Dir
|
||||
*/
|
||||
uint8 len; /* Weitere L„nge */
|
||||
uint8 data[2]; /* Dateiname mit Wild */
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
uint8 len; /* fnname len */
|
||||
uint8 data[2]; /* fnname with wildcards */
|
||||
} *input = (struct INPUT *) ncprequest;
|
||||
int len=input->len ; /* FN Length */
|
||||
|
||||
struct OUTPUT {
|
||||
uint8 searchsequence[2]; /* FRAGE Sequence */
|
||||
uint8 dir_id[2]; /* Direktory ID */
|
||||
@ -838,7 +853,8 @@ static void handle_ncp_serv()
|
||||
} u;
|
||||
} *xdata = (struct OUTPUT*)responsedata;
|
||||
|
||||
int searchsequence = nw_dir_search( (uint8*) &(xdata->u),
|
||||
int searchsequence = nw_dir_search(
|
||||
(uint8*) &(xdata->u),
|
||||
(int) GET_BE16(input->dir_id),
|
||||
(int) GET_BE16(input->searchsequence),
|
||||
(int) input->search_attrib,
|
||||
@ -1020,7 +1036,6 @@ static void handle_ncp_serv()
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0x48 : /* read file */
|
||||
{
|
||||
struct INPUT {
|
||||
@ -1171,56 +1186,14 @@ static void handle_ncp_serv()
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 0x57 : /* some new calls */
|
||||
{
|
||||
uint8 ufunc = *(requestdata);
|
||||
completition = 0xfb; /* erstmal */
|
||||
if (ufunc == 0x02) { /* Initialize Search */
|
||||
uint8 namespace=*(requestdata+1);
|
||||
uint8 reserved=*(requestdata+2);
|
||||
/* NW PATH STRUC */
|
||||
} else if (ufunc == 0x07) { /* Modify File or Dir Info */
|
||||
uint8 namespace=*(requestdata+1);
|
||||
} else if (ufunc == 0x09) { /* Set short Dir Handle*/
|
||||
uint8 namespace=*(requestdata+1);
|
||||
uint8 datastream=*(requestdata+2);
|
||||
uint8 desthandle=*(requestdata+3);
|
||||
/* 1 Byte Reserved */
|
||||
/* NWPATH STRUC */
|
||||
} else if (ufunc == 0x15) { /* Get Path String from short dir neu*/
|
||||
uint8 namespace=*(requestdata+1);
|
||||
uint8 short_dir_handle=*(requestdata+2);
|
||||
} else if (ufunc == 0x16) {
|
||||
/* Generate Dir BASE and VolNumber */
|
||||
uint8 namespace = *(requestdata+1);
|
||||
uint8 *nwpathstruct = requestdata+4;
|
||||
struct OUTPUT {
|
||||
uint8 ns_dir_base[4]; /* BASEHANDLE */
|
||||
uint8 dos_dir_base[4]; /* BASEHANDLE */
|
||||
uint8 volume; /* Volumenumber*/
|
||||
} *xdata= (struct OUTPUT*)responsedata;
|
||||
int result = nw_generate_dir_path(nwpathstruct,
|
||||
xdata->ns_dir_base, xdata->dos_dir_base);
|
||||
if (result >-1) {
|
||||
data_len = sizeof(struct OUTPUT);
|
||||
xdata->volume = result;
|
||||
completition=0;
|
||||
} else completition = (uint8)(-result);
|
||||
} else if (ufunc == 0x0c) { /* alloc short dir Handle */
|
||||
uint8 namespace = *(requestdata+1);
|
||||
int allocatemode = GET_BE16(requestdata+2);
|
||||
/* NWPATH STRUC */
|
||||
} else if (ufunc == 0x1a) { /* Get Huge NS Info neu*/
|
||||
uint8 namespace=*(requestdata+1);
|
||||
} else if (ufunc == 0x1c) { /* GetFullPathString neu*/
|
||||
uint8 snamespace=*(requestdata+1);
|
||||
uint8 dnamespace=*(requestdata+2);
|
||||
} else if (ufunc == 0x1d) { /* GetEffDirRights neu*/
|
||||
uint8 namespace=*(requestdata+1);
|
||||
}
|
||||
} break;
|
||||
case 0x57 : /* some new namespace calls */
|
||||
int result = handle_func_0x57(requestdata, responsedata);
|
||||
if (result > -1) data_len = result;
|
||||
else completition=(uint8)-result;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
case 0x61 : { /* Negotiate Buffer Size, Packetsize new ??? */
|
||||
/* same request as 0x21 */
|
||||
@ -1238,45 +1211,65 @@ static void handle_ncp_serv()
|
||||
printf("WRONG TYPE 0x%x IN NWCONN\n", ncp_type);
|
||||
completition = 0xfb;
|
||||
}
|
||||
if (completition == 0xfb || (do_druck == 1)) { /* UNKWON FUNCTION od. TYPE */
|
||||
|
||||
if (nw_debug && (completition == 0xfb || (do_druck == 1))) { /* UNKWON FUNCTION od. TYPE */
|
||||
int x_nw_debug = nw_debug;
|
||||
if (!nw_debug || do_druck == 1) {
|
||||
if (nw_debug == 1 || do_druck == 1) {
|
||||
int j = requestlen;
|
||||
nw_debug = 1;
|
||||
DPRINTF(("NCP REQUEST: seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||||
nw_debug = 2;
|
||||
XDPRINTF((2,"NCP REQUEST: seq:%d, task:%d, reserved:0x%x, func:0x%x\n",
|
||||
sequence, task, reserved, function));
|
||||
if (j > 0){
|
||||
uint8 *p=requestdata;
|
||||
DPRINTF(("len %d, DATA:", j));
|
||||
XDPRINTF((2,"len %d, DATA:", j));
|
||||
while (j--) {
|
||||
int c = *p++;
|
||||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||||
else DPRINTF((",0x%x", c));
|
||||
if (c > 32 && c < 127) XDPRINTF((2,",\'%c\'", (char) c));
|
||||
else XDPRINTF((2,",0x%x", c));
|
||||
}
|
||||
DPRINTF(("\n"));
|
||||
XDPRINTF((2,"\n"));
|
||||
}
|
||||
}
|
||||
if (completition == 0xfb)
|
||||
DPRINTF(("UNKNOWN FUNCTION od. TYPE: 0x%x\n", function));
|
||||
XDPRINTF((1,"UNKNOWN FUNCTION od. TYPE: 0x%x\n", function));
|
||||
else if (data_len){
|
||||
int j = data_len;
|
||||
uint8 *p = responsedata;
|
||||
DPRINTF(("RSPONSE: len %d, DATA:", data_len));
|
||||
XDPRINTF((2,"RSPONSE: len %d, DATA:", data_len));
|
||||
while (j--) {
|
||||
int c = *p++;
|
||||
if (c > 32 && c < 127) DPRINTF((",\'%c\'", (char) c));
|
||||
else DPRINTF((",0x%x", c));
|
||||
if (c > 32 && c < 127) XDPRINTF((2,",\'%c\'", (char) c));
|
||||
else XDPRINTF((2,",0x%x", c));
|
||||
}
|
||||
DPRINTF(("\n"));
|
||||
XDPRINTF((2,"\n"));
|
||||
}
|
||||
nw_debug = x_nw_debug;
|
||||
}
|
||||
|
||||
ncp_response(sequence, completition, data_len);
|
||||
if (nw_debug != 99 && nw_debug != -99) nw_debug = org_nw_debug;
|
||||
else if (nw_debug == -99) nw_debug = 0;
|
||||
}
|
||||
|
||||
extern int t_errno;
|
||||
|
||||
static void close_all(void)
|
||||
{
|
||||
nw_init_connect();
|
||||
close(0);
|
||||
if (ipx_fd > -1){
|
||||
while (t_unbind(ipx_fd) < 0) {
|
||||
if (t_errno != TOUTSTATE) break;
|
||||
}
|
||||
t_close(ipx_fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_quit(int rsig)
|
||||
{
|
||||
close_all();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int fl_get_debug=0;
|
||||
static void get_new_debug(void)
|
||||
{
|
||||
@ -1291,27 +1284,35 @@ static void sig_hup(int rsig)
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
extern int t_errno;
|
||||
static void set_sig(void)
|
||||
{
|
||||
signal(SIGTERM, sig_quit);
|
||||
signal(SIGQUIT, sig_quit);
|
||||
signal(SIGHUP, sig_hup);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int completition = 0;
|
||||
if (argc != 8) {
|
||||
printf("usage nwconn PID FROM_ADDR Connection UID GID Debug1 Debugipx\n");
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection\n");
|
||||
exit(1);
|
||||
} else father_pid = atoi(*(argv+1));
|
||||
setuid(0);
|
||||
setgid(0);
|
||||
|
||||
init_tools(NWCONN);
|
||||
|
||||
DPRINTF(("FATHER PID=%d, ADDR=%s CON:%s\n", father_pid, *(argv+2), *(argv+3)));
|
||||
adr_to_ipx_addr(&from_addr, *(argv+2));
|
||||
|
||||
default_gid = atoi(*(argv+4));
|
||||
default_uid = atoi(*(argv+5));
|
||||
nw_debug = atoi(*(argv+6));
|
||||
ipxdebug = atoi(*(argv+7));
|
||||
if (nw_init_connect()) exit(1);
|
||||
|
||||
#ifdef LINUX
|
||||
set_emu_tli(ipxdebug);
|
||||
set_emu_tli();
|
||||
#endif
|
||||
if (nw_init_connect()) exit(1);
|
||||
|
||||
last_sequence = -9999;
|
||||
if (open_ipx_socket()) exit(1);
|
||||
@ -1331,7 +1332,7 @@ int main(int argc, char **argv)
|
||||
ncpresponse->reserved = (uint8) 0; /* allways 0 */
|
||||
ncpresponse->connection = (uint8) atoi(*(argv+3));
|
||||
|
||||
signal(SIGHUP, sig_hup);
|
||||
set_sig();
|
||||
|
||||
while (1) {
|
||||
int data_len = read(0, readbuff, sizeof(readbuff));
|
||||
@ -1352,19 +1353,11 @@ int main(int argc, char **argv)
|
||||
requestlen = data_len - sizeof(NCPREQUEST);
|
||||
handle_ncp_serv();
|
||||
}
|
||||
|
||||
} else if (data_len < 0) {
|
||||
if (fl_get_debug) get_new_debug();
|
||||
else break;
|
||||
}
|
||||
}
|
||||
close(0);
|
||||
|
||||
if (ipx_fd > -1){
|
||||
while ((completition = t_unbind(ipx_fd)) < 0) {
|
||||
if (t_errno != TOUTSTATE) break;
|
||||
}
|
||||
t_close(ipx_fd);
|
||||
}
|
||||
close_all();
|
||||
return(0);
|
||||
}
|
||||
|
213
nwcrypt.c
Normal file
213
nwcrypt.c
Normal file
@ -0,0 +1,213 @@
|
||||
/*$*********************************************************
|
||||
$*
|
||||
$* This code has been taken from DDJ 11/93, from an
|
||||
$* article by Pawel Szczerbina.
|
||||
$*
|
||||
$* Password encryption routines follow.
|
||||
$* Converted to C from Barry Nance's Pascal
|
||||
$* prog published in the March -93 issue of Byte.
|
||||
$*
|
||||
$* Adapted to be useable for ncpfs by
|
||||
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
|
||||
$* October 1995.
|
||||
$*
|
||||
$* Stolen to be useable for mars_nwe by
|
||||
$* Martin Stover <mstover@freeway.de> in
|
||||
$* Dezember 1995.
|
||||
$**********************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
I read that Novell is not very open when it comes to technical details
|
||||
of the Netware Core Protocol. This might be especially true for the
|
||||
encryption stuff. I took the necessary code from Dr. Dobb's Journal
|
||||
11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
|
||||
the legal status of this piece of code:
|
||||
|
||||
|
||||
---
|
||||
Date: Thu, 12 Oct 1995 13:44:18 +0100
|
||||
From: Volker Lendecke <lendecke>
|
||||
To: jon@ddj.com
|
||||
Subject: legal status of your source code?
|
||||
|
||||
|
||||
Hello!
|
||||
|
||||
I hope that you're the right one to write to, you are the first on your WWW
|
||||
server. If you are not, could you please forward this message to the right
|
||||
person? Thanks.
|
||||
|
||||
I'm currently exploring the possibility to write a free (in the GNU GPL
|
||||
sense) NCP filesystem, which would allow me to access a novell server
|
||||
transparently. For that I would like to use the encryption functions you
|
||||
published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
|
||||
changes, such as other indentations, minor code changes and so on. But I do
|
||||
not know if that allows me to publish this code under GPL. One alternative
|
||||
would be to publish a diff against your listing, but that would probably
|
||||
contain much of your code as well, and it would be very inconvenient for
|
||||
the average user.
|
||||
|
||||
I think that you have some kind of standard procedure for such a
|
||||
case. Please tell me what I should do.
|
||||
|
||||
Many thanks in advance,
|
||||
|
||||
Volker
|
||||
|
||||
+=================================================================+
|
||||
! Volker Lendecke Internet: lendecke@namu01.gwdg.de !
|
||||
! D-37081 Goettingen, Germany !
|
||||
+=================================================================+
|
||||
|
||||
--
|
||||
|
||||
|
||||
I got the following answer:
|
||||
|
||||
---
|
||||
From: Jon Erickson <jon@ddj.com>
|
||||
X-Mailer: SCO System V Mail (version 3.2)
|
||||
To: lendecke@namu01.gwdg.de
|
||||
Subject: Re: legal status of your source code?
|
||||
Date: Thu, 12 Oct 95 5:42:56 PDT
|
||||
|
||||
Volker,
|
||||
Code from Dr. Dobb's Journal related articles is provided for
|
||||
anyone to use. Clearly, the author of the article should be
|
||||
given credit.
|
||||
Jon Erickson
|
||||
|
||||
---
|
||||
|
||||
With this answer in mind, I took the code and made it a bit more
|
||||
C-like. The original seemed to be translated by a mechanical pascal->c
|
||||
translator. Jon's answer encouraged me to publish nwcrypt.c under the
|
||||
GPL. If anybody who knows more about copyright and sees any problems
|
||||
with this, please tell me.
|
||||
****************************************************************************/
|
||||
|
||||
/******************* Data types ***************************/
|
||||
typedef unsigned char buf32[32];
|
||||
typedef unsigned char buf16[16];
|
||||
typedef unsigned char buf8[8];
|
||||
typedef unsigned char buf4[4];
|
||||
typedef unsigned char u8;
|
||||
|
||||
static u8 encrypttable[256] =
|
||||
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
|
||||
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
|
||||
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
|
||||
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
|
||||
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
|
||||
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
|
||||
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
|
||||
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
|
||||
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
|
||||
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
|
||||
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
|
||||
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
|
||||
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
|
||||
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
|
||||
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
|
||||
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
|
||||
|
||||
static buf32 encryptkeys =
|
||||
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
|
||||
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
|
||||
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
||||
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
||||
|
||||
|
||||
static void
|
||||
shuffle1(buf32 temp, unsigned char *target)
|
||||
{
|
||||
short b4;
|
||||
unsigned char b3;
|
||||
int s, b2, i;
|
||||
|
||||
b4 = 0;
|
||||
|
||||
for (b2 = 0; b2 <= 1; ++b2)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]);
|
||||
b4 = b4 + b3;
|
||||
temp[s] = b3;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 15; ++i) {
|
||||
target[i] = encrypttable[temp[ 2*i ]]
|
||||
| (encrypttable[temp[ 2*i + 1]] << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
|
||||
unsigned char *target)
|
||||
{
|
||||
int b2, d, s;
|
||||
buf32 temp;
|
||||
|
||||
while ( (buflen > 0)
|
||||
&& (buf[buflen - 1] == 0)) {
|
||||
buflen = buflen - 1;
|
||||
}
|
||||
|
||||
for (s = 0; s < 32; s++) {
|
||||
temp[s] = 0;
|
||||
}
|
||||
|
||||
d = 0;
|
||||
while (buflen >= 32)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
temp[s] = temp[s] ^ buf[d];
|
||||
d = d + 1;
|
||||
}
|
||||
buflen = buflen - 32;
|
||||
}
|
||||
b2 = d;
|
||||
if (buflen > 0)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
if (d + buflen == b2)
|
||||
{
|
||||
b2 = d;
|
||||
temp[s] = temp[s] ^ encryptkeys[s];
|
||||
} else {
|
||||
temp[s] = temp[s] ^ buf[b2];
|
||||
b2 = b2 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] = temp[s] ^ lon[s & 3];
|
||||
|
||||
shuffle1(temp,target);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
|
||||
{
|
||||
buf32 k;
|
||||
int s;
|
||||
|
||||
shuffle(&(fra[0]), buf, 16, &(k[ 0]));
|
||||
shuffle(&(fra[4]), buf, 16, &(k[16]));
|
||||
|
||||
for (s = 0; s <= 15; ++s)
|
||||
k[s] = k[s] ^ k[31 - s];
|
||||
|
||||
for (s = 0; s <= 7; ++s)
|
||||
til[s] = k[s] ^ k[15 - s];
|
||||
}
|
||||
|
||||
|
310
nwdbm.c
310
nwdbm.c
@ -1,4 +1,4 @@
|
||||
/* nwdbm.c 22-Nov-95 data base for mars_nwe */
|
||||
/* nwdbm.c 05-Dec-95 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
|
||||
@ -29,6 +29,8 @@
|
||||
# include </usr/ucbinclude/ndbm.h>
|
||||
#endif
|
||||
|
||||
int tells_server_version=0;
|
||||
|
||||
static char *fnprop = "nwprop";
|
||||
static char *fnval = "nwval";
|
||||
static char *fnobj = "nwobj";
|
||||
@ -87,7 +89,7 @@ static int name_match(uint8 *s, uint8 *p)
|
||||
int find_obj_id(NETOBJ *o, uint32 last_obj_id)
|
||||
{
|
||||
int result = -0xfc; /* no Object */
|
||||
DPRINTF(("findobj_id OBJ=%s, type=0x%x, lastid=0x%lx \n",
|
||||
XDPRINTF((2, "findobj_id OBJ=%s, type=0x%x, lastid=0x%lx \n",
|
||||
o->name, (int)o->type, last_obj_id));
|
||||
|
||||
if (!dbminit(fnobj)){
|
||||
@ -107,7 +109,7 @@ int find_obj_id(NETOBJ *o, uint32 last_obj_id)
|
||||
NETOBJ *obj = (NETOBJ*)data.dptr;
|
||||
if ( ( ((int)obj->type == (int)o->type) || o->type == MAX_U16) &&
|
||||
name_match(obj->name, o->name)) {
|
||||
DPRINTF(("found OBJ=%s, id=0x%lx\n", obj->name, obj->id));
|
||||
XDPRINTF((2, "found OBJ=%s, id=0x%lx\n", obj->name, obj->id));
|
||||
result = 0;
|
||||
memcpy((char *)o, (char*)obj, sizeof(NETOBJ));
|
||||
} else {
|
||||
@ -131,7 +133,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
|
||||
int result = -0xfb; /* no property */
|
||||
memset(xset, 0, sizeof(xset));
|
||||
if (!prop_id) {
|
||||
DPRINTF(("loc_delete_property obj_id=%d, prop=%s\n", obj_id, prop_name));
|
||||
XDPRINTF((2, "loc_delete_property obj_id=%d, prop=%s\n", obj_id, prop_name));
|
||||
if (!dbminit(fnprop)){
|
||||
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
|
||||
NETPROP *p=(NETPROP*)key.dptr;
|
||||
@ -139,7 +141,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
|
||||
data = fetch(key);
|
||||
p = (NETPROP*)data.dptr;
|
||||
if (p != NULL && name_match(p->name, prop_name)){
|
||||
DPRINTF(("found prop: %s, id=%d for deleting\n", p->name, (int)p->id));
|
||||
XDPRINTF((2, "found prop: %s, id=%d for deleting\n", p->name, (int)p->id));
|
||||
if ((int)(p->id) > result) result = (int)(p->id);
|
||||
xset[p->id]++;
|
||||
}
|
||||
@ -148,7 +150,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
|
||||
} else result = -0xff;
|
||||
dbmclose();
|
||||
} else {
|
||||
DPRINTF(("loc_delete_property obj_id=%d, prop_id=%d\n", obj_id, (int)prop_id));
|
||||
XDPRINTF((2, "loc_delete_property obj_id=%d, prop_id=%d\n", obj_id, (int)prop_id));
|
||||
xset[prop_id]++;
|
||||
result = prop_id;
|
||||
}
|
||||
@ -211,7 +213,7 @@ static int loc_delete_obj(uint32 objid)
|
||||
int nw_delete_obj(NETOBJ *obj)
|
||||
{
|
||||
int result = find_obj_id(obj, 0);
|
||||
DPRINTF(("nw_delete_obj obj_id=%d, obj_name=%s\n", obj->id, obj->name));
|
||||
XDPRINTF((2, "nw_delete_obj obj_id=%d, obj_name=%s\n", obj->id, obj->name));
|
||||
if (!result) result=loc_delete_obj(obj->id);
|
||||
return(result);
|
||||
}
|
||||
@ -228,7 +230,7 @@ int nw_rename_obj(NETOBJ *o, uint8 *newname)
|
||||
data = fetch(key);
|
||||
if (data.dptr != NULL){
|
||||
NETOBJ *obj=(NETOBJ*)data.dptr;
|
||||
DPRINTF(("rename_obj:got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
XDPRINTF((2, "rename_obj:got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
strncpy(obj->name, newname, 48);
|
||||
if (!store(key, data)) result=0;
|
||||
}
|
||||
@ -250,7 +252,7 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity)
|
||||
data = fetch(key);
|
||||
if (data.dptr != NULL){
|
||||
NETOBJ *obj=(NETOBJ*)data.dptr;
|
||||
DPRINTF(("change_obj_security:got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
XDPRINTF((2, "change_obj_security:got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
obj->security = (uint8) newsecurity;
|
||||
if (!store(key, data)) result=0;
|
||||
}
|
||||
@ -263,14 +265,14 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity)
|
||||
int nw_get_obj(NETOBJ *o)
|
||||
{
|
||||
int result = -0xfc; /* no Object */
|
||||
DPRINTF(("nw_get_obj von OBJ id = 0x%x,\n", (int)o->id));
|
||||
XDPRINTF((2, "nw_get_obj von OBJ id = 0x%x,\n", (int)o->id));
|
||||
if (!dbminit(fnobj)){
|
||||
key.dsize = NETOBJ_KEY_SIZE;
|
||||
key.dptr = (char*)o;
|
||||
data = fetch(key);
|
||||
if (data.dptr != NULL){
|
||||
NETOBJ *obj=(NETOBJ*)data.dptr;
|
||||
DPRINTF(("got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
XDPRINTF((2, "got OBJ name=%s, id = 0x%x,\n", obj->name, (int)obj->id));
|
||||
memcpy(o, data.dptr, sizeof(NETOBJ));
|
||||
result = 0;
|
||||
}
|
||||
@ -282,7 +284,7 @@ int nw_get_obj(NETOBJ *o)
|
||||
static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id)
|
||||
{
|
||||
int result = -0xfb; /* no Property */
|
||||
DPRINTF(("find Prop id von name=0x%x:%s, lastid=%d\n",
|
||||
XDPRINTF((2, "find Prop id von name=0x%x:%s, lastid=%d\n",
|
||||
obj_id, p->name, last_prop_id));
|
||||
if (!dbminit(fnprop)){
|
||||
int flag = (last_prop_id) ? 0 : 1;
|
||||
@ -294,7 +296,7 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id)
|
||||
data = fetch(key);
|
||||
prop = (NETPROP*)data.dptr;
|
||||
if (data.dptr != NULL && name_match(prop->name, p->name) ) {
|
||||
DPRINTF(("found PROP %s, id=0x%x\n", prop->name, (int) prop->id));
|
||||
XDPRINTF((2, "found PROP %s, id=0x%x\n", prop->name, (int) prop->id));
|
||||
result = 0;
|
||||
memcpy(p, prop, sizeof(NETPROP));
|
||||
break;
|
||||
@ -314,7 +316,7 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id)
|
||||
static int loc_change_prop_security(NETPROP *p, uint32 obj_id)
|
||||
{
|
||||
int result = -0xfb; /* no Property */
|
||||
DPRINTF(("loc_change_prop_security Prop id von name=0x%x:%s\n", obj_id, p->name));
|
||||
XDPRINTF((2, "loc_change_prop_security Prop id von name=0x%x:%s\n", obj_id, p->name));
|
||||
if (!dbminit(fnprop)){
|
||||
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
|
||||
NETPROP *prop=(NETPROP*)key.dptr;
|
||||
@ -323,7 +325,7 @@ static int loc_change_prop_security(NETPROP *p, uint32 obj_id)
|
||||
prop = (NETPROP*)data.dptr;
|
||||
if (data.dptr != NULL && name_match(prop->name, p->name) ) {
|
||||
uint8 security = p->security;
|
||||
DPRINTF(("found PROP %s, id=0x%x\n", prop->name, (int) prop->id));
|
||||
XDPRINTF((2, "found PROP %s, id=0x%x\n", prop->name, (int) prop->id));
|
||||
result = 0;
|
||||
memcpy(p, prop, sizeof(NETPROP));
|
||||
p->security = security;
|
||||
@ -357,7 +359,7 @@ static int loc_get_prop_val(uint32 obj_id, int prop_id, int segment,
|
||||
if (data.dptr != NULL){
|
||||
NETVAL *v = (NETVAL*)data.dptr;
|
||||
if (NULL != property_value) memcpy(property_value, v->value, 128);
|
||||
DPRINTF(("found VAL 0x%x, %d, %d\n", obj_id, prop_id, segment));
|
||||
XDPRINTF((2, "found VAL 0x%x, %d, %d\n", obj_id, prop_id, segment));
|
||||
result = 0;
|
||||
val.segment++;
|
||||
data = fetch(key);
|
||||
@ -385,7 +387,7 @@ int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id)
|
||||
NETVAL *v = (NETVAL*)data.dptr;
|
||||
uint8 *p=v->value;
|
||||
int k=0;
|
||||
DPRINTF(("found VAL 0x%x, %d\n", obj_id, prop_id));
|
||||
XDPRINTF((2, "found VAL 0x%x, %d\n", obj_id, prop_id));
|
||||
while (k++ < 32){
|
||||
uint32 id = GET_BE32(p);
|
||||
if (id == member_id) {
|
||||
@ -522,7 +524,7 @@ int nw_get_prop_val_by_obj_id(uint32 obj_id,
|
||||
NETPROP prop;
|
||||
int result=-0xff;
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_get_prop_val_by_obj_id,id=0x%x, prop=%s, segment=%d\n",
|
||||
XDPRINTF((2, "nw_get_prop_val_by_obj_id,id=0x%x, prop=%s, segment=%d\n",
|
||||
obj_id, prop.name, segment_nr));
|
||||
|
||||
if ((result=find_first_prop_id(&prop, obj_id))==0){
|
||||
@ -566,7 +568,7 @@ int nw_delete_property(int object_type,
|
||||
int result=-0xff;
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)prop_name_x, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_delete_property obj=%s, prop=%s, type=0x%x\n",
|
||||
XDPRINTF((2, "nw_delete_property obj=%s, prop=%s, type=0x%x\n",
|
||||
obj.name, prop_name_x, object_type));
|
||||
obj.type = (uint16) object_type;
|
||||
if ((result = find_obj_id(&obj, 0)) == 0){
|
||||
@ -588,7 +590,7 @@ int nw_is_obj_in_set(int object_type,
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)mobj.name, (char*)member_name, member_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_is_obj_in_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
XDPRINTF((2, "nw_is_obj_in_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
obj.name, object_type, mobj.name, member_type, prop.name));
|
||||
obj.type = (uint16) object_type;
|
||||
mobj.type = (uint16) member_type;
|
||||
@ -615,7 +617,7 @@ int nw_add_obj_to_set(int object_type,
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)mobj.name, (char*)member_name, member_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_add_obj_to_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
XDPRINTF((2, "nw_add_obj_to_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
obj.name, object_type, mobj.name, member_type, prop.name));
|
||||
obj.type = (uint16) object_type;
|
||||
mobj.type = (uint16) member_type;
|
||||
@ -642,7 +644,7 @@ int nw_delete_obj_from_set(int object_type,
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)mobj.name, (char*)member_name, member_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_delete_obj_from_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
XDPRINTF((2, "nw_delete_obj_from_set obj=%s,0x%x, member=%s,0x%x, prop=%s\n",
|
||||
obj.name, object_type, mobj.name, member_type, prop.name));
|
||||
obj.type = (uint16) object_type;
|
||||
mobj.type = (uint16) member_type;
|
||||
@ -668,7 +670,7 @@ int nw_write_prop_value(int object_type,
|
||||
int result=-0xff;
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_write_prop_value obj=%s, prop=%s, type=0x%x, segment=%d\n",
|
||||
XDPRINTF((2, "nw_write_prop_value obj=%s, prop=%s, type=0x%x, segment=%d\n",
|
||||
obj.name, prop.name, object_type, segment_nr));
|
||||
obj.type = (uint16) object_type;
|
||||
|
||||
@ -694,7 +696,7 @@ int nw_change_prop_security(int object_type,
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
prop.security = (uint8)prop_security;
|
||||
DPRINTF(("nw_change_prop_security obj=%s,0x%x, prop=%s\n",
|
||||
XDPRINTF((2, "nw_change_prop_security obj=%s,0x%x, prop=%s\n",
|
||||
obj.name, object_type, prop.name));
|
||||
obj.type = (uint16) object_type;
|
||||
if ((result = find_obj_id(&obj, 0)) == 0){
|
||||
@ -715,7 +717,7 @@ int nw_scan_property(NETPROP *prop,
|
||||
int result;
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)prop->name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_scan_property obj=%s, prop=%s, type=0x%x, last_scan=0x%lx\n",
|
||||
XDPRINTF((2, "nw_scan_property obj=%s, prop=%s, type=0x%x, last_scan=0x%lx\n",
|
||||
obj.name, prop->name, object_type, *last_scan));
|
||||
obj.type = (uint16) object_type;
|
||||
|
||||
@ -742,9 +744,9 @@ int nw_get_prop_val_str(uint32 q_id, char *propname, uint8 *buff)
|
||||
buff, &more_segments, &property_flags);
|
||||
if (result > -1) {
|
||||
result=strlen(buff);
|
||||
DPRINTF(("nw_get_prop_val_str:%s len=%d, name=`%s`\n", propname, result, buff));
|
||||
XDPRINTF((2, "nw_get_prop_val_str:%s strlen=%d\n", propname, result));
|
||||
} else
|
||||
DPRINTF(("nw_get_prop_val_str:%s, result=0x%x\n", propname, result));
|
||||
XDPRINTF((2, "nw_get_prop_val_str:%s, result=0x%x\n", propname, result));
|
||||
return(result);
|
||||
}
|
||||
|
||||
@ -757,7 +759,7 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id)
|
||||
*/
|
||||
{
|
||||
int result = 0; /* OK */
|
||||
DPRINTF(("creat OBJ=%s,type=0x%x\n", obj->name, (int)obj->type));
|
||||
XDPRINTF((2, "creat OBJ=%s,type=0x%x\n", obj->name, (int)obj->type));
|
||||
if (!dbminit(fnobj)){
|
||||
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
|
||||
data = fetch(key);
|
||||
@ -771,7 +773,8 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id)
|
||||
}
|
||||
}
|
||||
if (!result){
|
||||
obj->id = (wanted_id) ? wanted_id -1 : 0;
|
||||
obj->id = (wanted_id) ? wanted_id -1 : (obj->type << 16) + 1;
|
||||
/* 1 is reserved for supervisor !!!! */
|
||||
key.dsize = NETOBJ_KEY_SIZE;
|
||||
key.dptr = (char*)obj;
|
||||
while(1) {
|
||||
@ -854,7 +857,7 @@ int nw_create_prop(int object_type,
|
||||
int result=-0xff;
|
||||
strmaxcpy((char*)obj.name, (char*)object_name, object_namlen);
|
||||
strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen);
|
||||
DPRINTF(("nw_create_prop obj=%s, prop=%s, type=0x%x\n",
|
||||
XDPRINTF((2, "nw_create_prop obj=%s, prop=%s, type=0x%x\n",
|
||||
obj.name, prop.name, object_type));
|
||||
obj.type = (uint16) object_type;
|
||||
if ((result = find_obj_id(&obj, 0)) == 0){
|
||||
@ -898,6 +901,114 @@ uint32 nw_new_create_prop(uint32 wanted_id,
|
||||
return(obj.id);
|
||||
}
|
||||
|
||||
struct passwd *nw_getpwnam(uint32 obj_id)
|
||||
{
|
||||
static struct passwd pwstat;
|
||||
char buff[200];
|
||||
if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){
|
||||
struct passwd *pw = getpwnam(buff);
|
||||
if (NULL != pw) {
|
||||
memcpy(&pwstat, pw, sizeof(struct passwd));
|
||||
XDPRINTF((2, "FOUND obj_id=0x%x, pwnam=%s, gid=%d, uid=%d\n",
|
||||
obj_id, buff, pw->pw_gid, pw->pw_uid));
|
||||
endpwent ();
|
||||
return(&pwstat);
|
||||
}
|
||||
endpwent ();
|
||||
}
|
||||
XDPRINTF((2, "NOT FOUND PWNAM of obj_id=0x%x\n", obj_id));
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
int get_guid(int *gid, int *uid, uint32 obj_id)
|
||||
/* searched for gid und uid of actual obj */
|
||||
{
|
||||
struct passwd *pw = nw_getpwnam(obj_id);
|
||||
if (NULL != pw) {
|
||||
*gid = pw->pw_gid;
|
||||
*uid = pw->pw_uid;
|
||||
return(0);
|
||||
} else {
|
||||
*gid = -1;
|
||||
*uid = -1;
|
||||
return(-0xff);
|
||||
}
|
||||
}
|
||||
|
||||
int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key)
|
||||
/* returns 0, if password ok and -0xff if not ok */
|
||||
{
|
||||
char buf[200];
|
||||
if (nw_get_prop_val_str(obj_id, "PASSWORD", buf) > 0) {
|
||||
uint8 keybuff[8];
|
||||
memcpy(keybuff, vgl_key, sizeof(keybuff));
|
||||
nw_encrypt(keybuff, buf, keybuff);
|
||||
return (memcmp(akt_key, keybuff, sizeof(keybuff)) ? -0xff : 0);
|
||||
} else return(0); /* no password */
|
||||
}
|
||||
|
||||
int nw_set_enpasswd(uint32 obj_id, uint8 *passwd)
|
||||
{
|
||||
nw_new_create_prop(obj_id, NULL, 0, 0, 0,
|
||||
"PASSWORD", P_FL_STAT|P_FL_ITEM, 0x44,
|
||||
passwd, 16);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nw_set_passwd(uint32 obj_id, char *password)
|
||||
{
|
||||
uint8 passwd[200];
|
||||
uint8 s_uid[4];
|
||||
U32_TO_BE32(obj_id, s_uid);
|
||||
shuffle(s_uid, password, strlen(password), passwd);
|
||||
#if 0
|
||||
XDPRINTF((2, "password %s->0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",
|
||||
password,
|
||||
(int)passwd[0],
|
||||
(int)passwd[1],
|
||||
(int)passwd[2],
|
||||
(int)passwd[3],
|
||||
(int)passwd[4],
|
||||
(int)passwd[5],
|
||||
(int)passwd[6],
|
||||
(int)passwd[7],
|
||||
(int)passwd[8],
|
||||
(int)passwd[9],
|
||||
(int)passwd[10],
|
||||
(int)passwd[11],
|
||||
(int)passwd[12],
|
||||
(int)passwd[13],
|
||||
(int)passwd[14],
|
||||
(int)passwd[15]));
|
||||
#endif
|
||||
return(nw_set_enpasswd(obj_id, passwd));
|
||||
}
|
||||
|
||||
int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id)
|
||||
/* addiert member to set, if member not in set */
|
||||
{
|
||||
int result = prop_find_member(obj_id, prop_id, member_id);
|
||||
if (-0xea == result)
|
||||
return(prop_add_member(obj_id, prop_id, member_id));
|
||||
else if (!result) result = -0xee; /* already exist */
|
||||
return(result);
|
||||
}
|
||||
|
||||
int nw_new_add_prop_member(uint32 obj_id, char *propname, uint32 member_id)
|
||||
/* addiert member to set, if member not in set */
|
||||
{
|
||||
NETPROP prop;
|
||||
int result;
|
||||
strmaxcpy(prop.name, propname, sizeof(prop.name));
|
||||
result = find_prop_id(&prop, obj_id, 0);
|
||||
if (!result) {
|
||||
if (-0xea == (result=prop_find_member(obj_id, prop.id, member_id)))
|
||||
return(prop_add_member(obj_id, prop.id, member_id));
|
||||
else if (!result) result = -0xee; /* already exist */
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void create_nw_db(char *fn, int allways)
|
||||
{
|
||||
char fname[200];
|
||||
@ -920,7 +1031,7 @@ static void add_pr_queue(uint32 q_id,
|
||||
uint32 su_id, uint32 ge_id)
|
||||
{
|
||||
uint8 buff[12];
|
||||
DPRINTF(("ADD Q=%s, V=%s, C=%s\n", q_name, q_directory, q_command));
|
||||
XDPRINTF((2, "ADD Q=%s, V=%s, C=%s\n", 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,
|
||||
@ -950,114 +1061,57 @@ static void add_pr_queue(uint32 q_id,
|
||||
|
||||
}
|
||||
|
||||
static void nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
|
||||
static uint32 add_user(uint32 u_id, uint32 g_id,
|
||||
char *name, char *unname, char *password)
|
||||
{
|
||||
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,
|
||||
(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);
|
||||
|
||||
if (unname && *unname)
|
||||
nw_new_create_prop(u_id, NULL, 0 , 0 , 0 ,
|
||||
"UNIX_USER", P_FL_ITEM, 0x33,
|
||||
(char*)unname, strlen(unname));
|
||||
|
||||
if (password && *password) nw_set_passwd(u_id, password);
|
||||
}
|
||||
|
||||
void nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
/* fills the Standardproperties */
|
||||
{
|
||||
char serverna[50];
|
||||
uint8 buff[12];
|
||||
uint32 su_id = 0x00000001;
|
||||
uint32 ge_id = 0x01000001;
|
||||
|
||||
uint32 guest_id = 0x02000001;
|
||||
uint32 serv_id = 0x03000001;
|
||||
uint32 nbo_id = 0x0B000001;
|
||||
uint32 ngr_id = 0x0C000001;
|
||||
uint32 ps1_id = 0x0D000001;
|
||||
uint32 q1_id = 0x0E000001;
|
||||
struct {
|
||||
uint8 account_exp_date[3];
|
||||
uint8 account_disable_flag;
|
||||
uint8 password_exp_date[3];
|
||||
uint8 grace_logins_remain;
|
||||
uint8 password_exp_internal[2];
|
||||
uint8 grace_login_reset;
|
||||
uint8 minimum_password;
|
||||
uint8 max_connections[2];
|
||||
uint8 login_time_map[42];
|
||||
uint8 last_log_time[6];
|
||||
uint8 restriction_flags;
|
||||
uint8 reserved;
|
||||
uint8 max_disk_usage[4];
|
||||
uint8 bad_logins[2];
|
||||
uint8 next_reset_time[4];
|
||||
uint8 bad_logins_address[12];
|
||||
} login_control;
|
||||
|
||||
U32_TO_BE32(ge_id, buff);
|
||||
su_id = /* Typ Flags Security */
|
||||
nw_new_create_prop(su_id, "SUPERVISOR", 0x1 , 0x0, 0x33,
|
||||
"GROUPS_I'M_IN", P_FL_SET, 0x31,
|
||||
(char*)buff, 4);
|
||||
|
||||
nw_new_create_prop(su_id, NULL, 0x1, 0, 0,
|
||||
"IDENTIFICATION", P_FL_ITEM, 0x31,
|
||||
"SUPERVISOR LONG", 15);
|
||||
|
||||
nw_new_create_prop(su_id, NULL , 0 , 0 , 0 ,
|
||||
"SECURITY_EQUALS", P_FL_SET, 0x32,
|
||||
(char*)buff, 4);
|
||||
|
||||
memset(&login_control, 0, sizeof(login_control));
|
||||
login_control.grace_logins_remain = 0xff;
|
||||
login_control.grace_login_reset = 0xff;
|
||||
memset(login_control.login_time_map, 0xff,
|
||||
sizeof(login_control.login_time_map));
|
||||
|
||||
login_control.max_disk_usage[0] = 0x7f;
|
||||
login_control.max_disk_usage[1] = 0xff;
|
||||
login_control.max_disk_usage[2] = 0xff;
|
||||
login_control.max_disk_usage[3] = 0xff;
|
||||
|
||||
nw_new_create_prop(su_id, NULL , 0 , 0 , 0 ,
|
||||
"LOGIN_CONTROL", P_FL_ITEM, 0x32,
|
||||
NULL, 0);
|
||||
#if 0
|
||||
(char*)&login_control, sizeof(login_control));
|
||||
#endif
|
||||
#if 0
|
||||
nw_new_create_prop(su_id, NULL , 0 , 0 , 0 ,
|
||||
"USER_DEFAULTS", P_FL_ITEM, 0x31,
|
||||
((char*)(&login_control))+4,
|
||||
sizeof(login_control) -4);
|
||||
#endif
|
||||
U32_TO_BE32(ge_id, buff);
|
||||
guest_id =
|
||||
nw_new_create_prop(guest_id, "GUEST", 0x1, 0x0, 0x31,
|
||||
"GROUPS_I'M_IN", P_FL_SET, 0x31,
|
||||
(char*)buff, 4);
|
||||
|
||||
nw_new_create_prop(guest_id, NULL , 0, 0, 0,
|
||||
"SECURITY_EQUALS", P_FL_SET, 0x32,
|
||||
(char*)buff, 4);
|
||||
|
||||
nbo_id =
|
||||
nw_new_create_prop(nbo_id, "NOBODY", 0x1, 0x0, 0x31,
|
||||
"GROUPS_I'M_IN", P_FL_SET, 0x31,
|
||||
(char*)buff, 4);
|
||||
|
||||
nw_new_create_prop(nbo_id, NULL , 0, 0, 0,
|
||||
"SECURITY_EQUALS", P_FL_SET, 0x32,
|
||||
(char*)buff, 4);
|
||||
|
||||
U32_TO_BE32(su_id, buff);
|
||||
U32_TO_BE32(guest_id, buff+4);
|
||||
U32_TO_BE32(nbo_id, buff+8);
|
||||
|
||||
FILE *f = open_nw_ini();
|
||||
ge_id =
|
||||
nw_new_create_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31,
|
||||
"GROUP_MEMBERS", P_FL_SET, 0x31,
|
||||
(char*)buff, 12);
|
||||
|
||||
ngr_id =
|
||||
nw_new_create_prop(ngr_id, "NOGROUP", 0x2, 0x0, 0x31,
|
||||
"GROUP_MEMBERS", P_FL_SET, 0x31,
|
||||
NULL, 0);
|
||||
|
||||
{
|
||||
FILE *f=open_nw_ini();
|
||||
if (f){
|
||||
char buff[500];
|
||||
int what;
|
||||
while (0 != (what =get_ini_entry(f, 21, (char*)buff, sizeof(buff)))) {
|
||||
while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) {
|
||||
if (6 == what) { /* Server Version */
|
||||
tells_server_version = atoi(buff);
|
||||
} else if (21 == what) { /* QUEUES */
|
||||
char name[100];
|
||||
char directory[200];
|
||||
char command[200];
|
||||
@ -1091,15 +1145,29 @@ static 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 */
|
||||
char nname[100];
|
||||
char uname[100];
|
||||
char password[100];
|
||||
int anz=sscanf((char*)buff, "%s %s %s", nname, uname, password);
|
||||
if (anz > 1) {
|
||||
upstr(nname);
|
||||
if (anz > 2) upstr(password);
|
||||
else password[0] = '\0';
|
||||
add_user((12 == what) ? su_id : 0L, ge_id, nname,
|
||||
uname, password);
|
||||
}
|
||||
}
|
||||
} /* while */
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
if (servername && adr) {
|
||||
strmaxcpy(serverna, servername, 48);
|
||||
upstr(serverna);
|
||||
nw_new_create_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40,
|
||||
"NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40,
|
||||
(char*)adr, sizeof(ipxAddr_t));
|
||||
}
|
||||
}
|
||||
|
||||
void nw_init_dbm(char *servername, ipxAddr_t *adr)
|
||||
|
3
nwdbm.h
3
nwdbm.h
@ -58,6 +58,8 @@ typedef struct {
|
||||
#define P_FL_ITEM 0x0
|
||||
#define P_FL_SET 0x2
|
||||
|
||||
extern int tells_server_version;
|
||||
|
||||
extern int nw_get_prop(int object_type,
|
||||
uint8 *object_name, int object_namlen,
|
||||
int segment_nr,
|
||||
@ -166,5 +168,6 @@ extern uint32 nw_new_create_prop(uint32 wanted_id,
|
||||
char *propname, int propflags, int propsecurity,
|
||||
char *value, int valuesize);
|
||||
|
||||
extern void nw_fill_standard(char *servername, ipxAddr_t *adr);
|
||||
extern void nw_init_dbm(char *servername, ipxAddr_t *adr);
|
||||
|
||||
|
335
nwroute.c
Normal file
335
nwroute.c
Normal file
@ -0,0 +1,335 @@
|
||||
/* nwroute.c 20-Dec-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"
|
||||
#include "nwserv.h"
|
||||
|
||||
#define MAX_NW_ROUTES 50 /* max. 1 complete RIP packet should be enough */
|
||||
|
||||
typedef struct {
|
||||
uint32 net; /* destnet */
|
||||
uint16 hops; /* hops to net */
|
||||
uint16 ticks; /* ticks to net, ether 1/hop, isdn 7/hop */
|
||||
|
||||
uint32 rnet; /* net of forw. router */
|
||||
uint8 rnode[IPX_NODE_SIZE]; /* node of forw. router */
|
||||
} NW_ROUTES;
|
||||
|
||||
static int anz_routes=0;
|
||||
static NW_ROUTES *nw_routes[MAX_NW_ROUTES];
|
||||
|
||||
static void insert_delete_net(uint32 destnet,
|
||||
uint32 rnet, /* routernet */
|
||||
uint8 *rnode, /* routernode */
|
||||
uint16 hops,
|
||||
uint16 ticks,
|
||||
int do_delete) /* delete == 1 */
|
||||
{
|
||||
int k=-1;
|
||||
int freeslot=-1;
|
||||
NW_ROUTES *nr=NULL;
|
||||
|
||||
XDPRINTF((3,"%s net:0x%X, over 0x%X, 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
(do_delete) ? "DEL" : "INS", destnet, rnet,
|
||||
(int)rnode[0], (int)rnode[1], (int)rnode[2],
|
||||
(int)rnode[3], (int)rnode[4], (int)rnode[5]));
|
||||
|
||||
if (!destnet || destnet == internal_net) return;
|
||||
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->net == destnet && (do_delete || (nd->ticks <= ticks))) return;
|
||||
}
|
||||
|
||||
k=-1;
|
||||
while (++k < anz_routes && nw_routes[k]->net != destnet) {
|
||||
XDPRINTF((3,"NET 0x%X is routed\n", nw_routes[k]->net));
|
||||
if (freeslot < 0 && !nw_routes[k]->net) freeslot=k;
|
||||
}
|
||||
|
||||
if (k == anz_routes) { /* no route slot found */
|
||||
if (do_delete) return; /* nothing to delete */
|
||||
if (freeslot < 0) {
|
||||
if (anz_routes == MAX_NW_ROUTES) return;
|
||||
nw_routes[k] = (NW_ROUTES*)xmalloc(sizeof(NW_ROUTES));
|
||||
anz_routes++;
|
||||
} else k=freeslot;
|
||||
nr=nw_routes[k];
|
||||
memset(nr, 0, sizeof(NW_ROUTES));
|
||||
nr->net = destnet;
|
||||
nr->ticks = 0xffff;
|
||||
nr->hops = 0xffff;
|
||||
} else if (do_delete) {
|
||||
nr=nw_routes[k];
|
||||
if (nr->rnet == rnet &&
|
||||
IPXCMPNODE(nr->rnode, rnode) ) {
|
||||
/* only delete the routes, which we have inserted */
|
||||
XDPRINTF((2,"ROUTE DEL NET=0x%X over Router NET 0x%X\n",
|
||||
nr->net, rnet));
|
||||
ipx_route_del(nr->net);
|
||||
nr->net = 0L;
|
||||
} else {
|
||||
XDPRINTF((3,"ROUTE NOT deleted NET=0x%X, RNET=0X%X\n",
|
||||
nr->net, rnet));
|
||||
}
|
||||
return;
|
||||
} else nr=nw_routes[k];
|
||||
if (ticks <= nr->ticks) {
|
||||
if (ticks > nr->ticks) return;
|
||||
if (ticks == nr->ticks && hops > nr->hops) return;
|
||||
nr->hops = hops;
|
||||
nr->ticks = ticks;
|
||||
nr->rnet = rnet;
|
||||
memcpy(nr->rnode, rnode, IPX_NODE_SIZE);
|
||||
XDPRINTF((2,"ADD ROUTE NET=0x%X, over 0x%X, 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
nr->net, nr->rnet,
|
||||
(int)nr->rnode[0], (int)nr->rnode[1], (int)nr->rnode[2],
|
||||
(int)nr->rnode[3], (int)nr->rnode[4], (int)nr->rnode[5]));
|
||||
ipx_route_add(nr->net, nr->rnet, nr->rnode);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 rnet=0L;
|
||||
static int rentries=0;
|
||||
static int rmode; /* 0=normal, 1=shutdown, 10=request */
|
||||
static uint8 rip_buff[402]; /* operation + max. 50 RIPS */
|
||||
|
||||
static void init_rip_buff(uint32 net, int mode)
|
||||
{
|
||||
rnet=net;
|
||||
rentries=0;
|
||||
rmode=mode;
|
||||
U16_TO_BE16((mode > 9) ? 1 : 2, rip_buff); /* rip request or response */
|
||||
}
|
||||
|
||||
static void ins_rip_buff(uint32 net, uint16 hops, uint16 ticks)
|
||||
{
|
||||
if ( net && rentries < 50 &&
|
||||
(net != rnet || (!rentries && net == internal_net))) {
|
||||
uint8 *p=rip_buff+2+(rentries*8);
|
||||
U32_TO_BE32(net, p);
|
||||
U16_TO_BE16(hops, p+4);
|
||||
U16_TO_BE16(ticks, p+6);
|
||||
rentries++;
|
||||
}
|
||||
}
|
||||
|
||||
static void build_rip_buff(uint32 destnet)
|
||||
{
|
||||
int is_wild = (destnet==MAX_U32);
|
||||
int is_response = (rmode < 10);
|
||||
int k;
|
||||
|
||||
if (!destnet) return;
|
||||
if (is_wild) rentries=0;
|
||||
|
||||
if (is_response) {
|
||||
if (is_wild || internal_net == destnet) {
|
||||
ins_rip_buff(internal_net, (rmode==1) ? 16 : 1,
|
||||
(rnet==internal_net) ? 1 : 2);
|
||||
}
|
||||
k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (is_wild || nd->net == destnet)
|
||||
ins_rip_buff(nd->net, (rmode==1) ? 16 : 1, nd->ticks+1);
|
||||
}
|
||||
}
|
||||
k=-1;
|
||||
while (++k < anz_routes) {
|
||||
NW_ROUTES *nr=nw_routes[k];
|
||||
if ((is_wild || nr->net == destnet) && rmode==1 || nr->hops < 2)
|
||||
ins_rip_buff(nr->net, (rmode==1) ? 16 : nr->hops, nr->ticks);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_rip_buff(ipxAddr_t *from_addr)
|
||||
{
|
||||
if (rentries > 0) {
|
||||
int datasize=(rentries*8)+2;
|
||||
ipxAddr_t to_addr;
|
||||
if (from_addr) memcpy(&to_addr, from_addr, sizeof(ipxAddr_t));
|
||||
else {
|
||||
memset(&to_addr, 0, sizeof(ipxAddr_t));
|
||||
U32_TO_BE32(rnet, to_addr.net);
|
||||
memset(to_addr.node, 0xFF, IPX_NODE_SIZE);
|
||||
U16_TO_BE16(SOCK_RIP, to_addr.sock);
|
||||
}
|
||||
|
||||
if (nw_debug) {
|
||||
uint8 *p = rip_buff;
|
||||
int operation = GET_BE16(p);
|
||||
XDPRINTF((2,"Send Rip %s entries=%d\n",
|
||||
(operation==1) ? "Request" : "Response", rentries));
|
||||
p+=2;
|
||||
while (rentries--) {
|
||||
uint32 net = GET_BE32(p);
|
||||
uint16 hops = GET_BE16(p+4);
|
||||
uint16 ticks = GET_BE16(p+6);
|
||||
XDPRINTF((2,"hops=%3d, ticks %3d, network:%02x.%02x.%02x.%02x\n",
|
||||
(int)hops, (int)ticks, (int)*(p), (int)*(p+1), (int)*(p+2), (int)*(p+3)));
|
||||
p+=8;
|
||||
}
|
||||
}
|
||||
|
||||
send_ipx_data(sockfd[RIP_SLOT], 1,
|
||||
datasize,
|
||||
(char *)rip_buff,
|
||||
&to_addr, "SEND RIP");
|
||||
rentries=0;
|
||||
}
|
||||
}
|
||||
|
||||
void send_rip_broadcast(int mode)
|
||||
/* mode=0, standard broadcast */
|
||||
/* mode=1, first trie */
|
||||
/* mode=2, shutdown */
|
||||
{
|
||||
int k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */
|
||||
init_rip_buff(nd->net, (mode == 2) ? 1 : 0);
|
||||
build_rip_buff(MAX_U32);
|
||||
send_rip_buff(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rip_for_net(uint32 net)
|
||||
{
|
||||
int k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */
|
||||
init_rip_buff(nd->net, 10);
|
||||
ins_rip_buff(net, MAX_U16, MAX_U16);
|
||||
send_rip_buff(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_rip(int fd, int ipx_pack_typ,
|
||||
int data_len, IPX_DATA *ipxdata,
|
||||
ipxAddr_t *from_addr)
|
||||
{
|
||||
int operation = GET_BE16(ipxdata->rip.operation);
|
||||
int entries = (data_len-2) / 8;
|
||||
uint8 *p = ((uint8*)ipxdata)+2;
|
||||
int is_response = operation==2;
|
||||
|
||||
XDPRINTF((2,"Got Rip %s entries=%d from: %s\n",
|
||||
(!is_response) ? "Request" : "Response", entries,
|
||||
visable_ipx_adr(from_addr)));
|
||||
|
||||
if (!is_response) {
|
||||
if (operation != 1) {
|
||||
XDPRINTF((1,"UNKNOWN RIP operation %d\n", operation));
|
||||
return;
|
||||
}
|
||||
init_rip_buff(GET_BE32(from_addr->net), 0);
|
||||
}
|
||||
|
||||
while (entries--) {
|
||||
uint32 net = GET_BE32(p);
|
||||
uint16 hops = GET_BE16(p+4);
|
||||
uint16 ticks = GET_BE16(p+6);
|
||||
XDPRINTF((2,"hops=%3d, ticks %3d, network:%02x.%02x.%02x.%02x\n",
|
||||
(int)hops, (int)ticks, (int)*(p), (int)*(p+1), (int)*(p+2), (int)*(p+3)));
|
||||
|
||||
if (is_response) {
|
||||
insert_delete_net(net, GET_BE32(from_addr->net),
|
||||
from_addr->node, hops+1, ticks+1, (hops > 15) ? 1 : 0);
|
||||
} else { /* rip request */
|
||||
build_rip_buff(net);
|
||||
if (net == MAX_U32) break;
|
||||
}
|
||||
p+=8;
|
||||
}
|
||||
if (!is_response) /* rip request */
|
||||
send_rip_buff(from_addr);
|
||||
}
|
||||
|
||||
/* <========================= SAP ============================> */
|
||||
void send_sap_broadcast(int mode)
|
||||
/* mode=0, standard broadcast */
|
||||
/* mode=1, first trie */
|
||||
/* mode=2, shutdown */
|
||||
{
|
||||
int k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->ticks < 7 || mode) { /* isdn devices should not get SAP broadcasts everytime */
|
||||
IPX_DATA ipx_data;
|
||||
ipxAddr_t wild;
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
|
||||
U32_TO_BE32(nd->net, wild.net);
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
|
||||
memset(&ipx_data, 0, sizeof(ipx_data.sip));
|
||||
strcpy(ipx_data.sip.server_name, my_nwname);
|
||||
memcpy(&ipx_data.sip.server_adr, &my_server_adr, sizeof(ipxAddr_t));
|
||||
U16_TO_BE16(SOCK_NCP, ipx_data.sip.server_adr.sock);
|
||||
/* use NCP SOCKET */
|
||||
|
||||
U16_TO_BE16(2, ipx_data.sip.response_type); /* General */
|
||||
U16_TO_BE16(4, ipx_data.sip.server_type); /* Fileserver */
|
||||
|
||||
if (mode == 2) {
|
||||
U16_TO_BE16(16, ipx_data.sip.intermediate_networks);
|
||||
} else {
|
||||
U16_TO_BE16(1, ipx_data.sip.intermediate_networks);
|
||||
/* I hope 1 is ok here */
|
||||
}
|
||||
send_ipx_data(sockfd[MY_BROADCAST_SLOT], 0,
|
||||
sizeof(ipx_data.sip),
|
||||
(char *)&(ipx_data.sip),
|
||||
&wild, "SIP Broadcast");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void query_sap_on_net(uint32 net)
|
||||
/* searches for the next server on this network */
|
||||
{
|
||||
SQP sqp;
|
||||
ipxAddr_t wild;
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
U32_TO_BE32(net, wild.net);
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
U16_TO_BE16(3, sqp.query_type);
|
||||
U16_TO_BE16(4, sqp.server_type);
|
||||
send_ipx_data(sockfd[SAP_SLOT], 17, sizeof(SQP),
|
||||
(char*)&sqp, &wild, "SERVER Query");
|
||||
}
|
||||
|
||||
void get_servers(void)
|
||||
{
|
||||
int k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->ticks < 7) query_sap_on_net(nd->net); /* only fast routes */
|
||||
}
|
||||
if (!anz_net_devices) query_sap_on_net(internal_net);
|
||||
}
|
||||
|
||||
|
649
nwserv.c
649
nwserv.c
@ -1,4 +1,4 @@
|
||||
/* nwserv.c 22-Nov-95 */
|
||||
/* nwserv.c 20-Dec-95 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -17,24 +17,15 @@
|
||||
*/
|
||||
|
||||
#include "net.h"
|
||||
#include "nwserv.h"
|
||||
|
||||
static int conn_gid=1;
|
||||
static int conn_uid=1;
|
||||
uint32 internal_net = 0x0L; /* NETWORKNUMMER INTERN (SERVER) */
|
||||
ipxAddr_t my_server_adr; /* Address of this server */
|
||||
char my_nwname[50]; /* Name of this server */
|
||||
|
||||
static int ncpserv_debug=0;
|
||||
static int nwconn_debug=0;
|
||||
|
||||
#define MY_BROADCAST_SLOT 0 /* Server Broadcast OUT */
|
||||
#define WDOG_SLOT 1 /* Watchdog send + recv */
|
||||
|
||||
#define SAP_SLOT 2
|
||||
#define RIP_SLOT 3
|
||||
#define ROUTE_SLOT 4
|
||||
#define DIAG_SLOT 5
|
||||
#if 0
|
||||
#define ECHO_SLOT 6
|
||||
#define ERR_SLOT 7
|
||||
#endif
|
||||
/* <========== DEVICES ==========> */
|
||||
int anz_net_devices=0;
|
||||
NW_NET_DEVICE *net_devices[MAX_NET_DEVICES];
|
||||
|
||||
uint16 ipx_sock_nummern[]={ 0, /* auto sock */
|
||||
0, /* auto sock */
|
||||
@ -42,10 +33,11 @@ uint16 ipx_sock_nummern[]={ 0, /* auto sock */
|
||||
SOCK_RIP,
|
||||
SOCK_ROUTE,
|
||||
SOCK_DIAGNOSE
|
||||
#if 0
|
||||
,
|
||||
SOCK_ECHO,
|
||||
SOCK_ERROR,
|
||||
#ifdef ECHO_SLOT
|
||||
, SOCK_ECHO
|
||||
#endif
|
||||
#ifdef ERROR_SLOT
|
||||
, SOCK_ERROR
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -54,39 +46,32 @@ uint16 ipx_sock_nummern[]={ 0, /* auto sock */
|
||||
|
||||
static uint16 sock_nummern [NEEDED_SOCKETS];
|
||||
|
||||
static int sockfd [NEEDED_SOCKETS];
|
||||
|
||||
int sockfd [NEEDED_SOCKETS];
|
||||
static struct pollfd polls[NEEDED_POLLS];
|
||||
|
||||
static ipxAddr_t my_server_adr; /* Address of this server */
|
||||
static uint16 spx_diag_socket; /* SPX DIAGNOSE SOCKET */
|
||||
static ipxAddr_t nw386_adr; /* Address of NW-TEST Server */
|
||||
static int nw386_found = 0;
|
||||
static int client_mode = 0;
|
||||
|
||||
static uint32 network = 0x0L;
|
||||
static uint32 internal_net = 0x0L;
|
||||
static char my_nwname[50];
|
||||
|
||||
static int ipxdebug = 0;
|
||||
static int pid_ncpserv = -1;
|
||||
static int fd_ncpserv_out = -1; /* ctrl-pipe out to ncpserv */
|
||||
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
|
||||
|
||||
#ifndef LINUX
|
||||
static int frame=0;
|
||||
#else
|
||||
static int frame=IPX_FRAME_8023;
|
||||
static char devname[40];
|
||||
#endif
|
||||
static time_t akttime_stamp;
|
||||
|
||||
static int bytes_to_write_to_ncpserv=0;
|
||||
static time_t akttime_stamp = 0;
|
||||
static int broadsecs = 2048;
|
||||
static time_t server_down_stamp = 0;
|
||||
static int server_goes_down_secs = 10;
|
||||
static int save_ipx_routes = 0;
|
||||
static int bytes_to_write_to_ncpserv = 0;
|
||||
|
||||
static void inform_ncpserv(void)
|
||||
{
|
||||
if (bytes_to_write_to_ncpserv) {
|
||||
if (bytes_to_write_to_ncpserv && pid_ncpserv > -1) {
|
||||
#if 0
|
||||
XDPRINTF((2, "inform_ncpserv bytes=%d\n", bytes_to_write_to_ncpserv));
|
||||
kill(pid_ncpserv, SIGHUP); /* tell ncpserv to read input */
|
||||
#endif
|
||||
bytes_to_write_to_ncpserv=0;
|
||||
}
|
||||
}
|
||||
@ -94,6 +79,9 @@ static void inform_ncpserv(void)
|
||||
static void write_to_ncpserv(int what, int connection,
|
||||
char *data, int data_size)
|
||||
{
|
||||
XDPRINTF((2, "write_to_ncpserv what=0x%x, conn=%d, data_size=%d\n",
|
||||
what, connection, data_size));
|
||||
|
||||
switch (what) {
|
||||
case 0x5555 : /* kill connection */
|
||||
bytes_to_write_to_ncpserv +=
|
||||
@ -111,6 +99,19 @@ static void write_to_ncpserv(int what, int connection,
|
||||
write(fd_ncpserv_out, data, data_size);
|
||||
break;
|
||||
|
||||
case 0xeeee : /* hup, read init */
|
||||
bytes_to_write_to_ncpserv +=
|
||||
write(fd_ncpserv_out, (char*) &what, sizeof(int));
|
||||
break;
|
||||
|
||||
case 0xffff : /* 'down server' */
|
||||
bytes_to_write_to_ncpserv +=
|
||||
write(fd_ncpserv_out, (char*) &what, sizeof(int));
|
||||
bytes_to_write_to_ncpserv +=
|
||||
write(fd_ncpserv_out, (char*) &what, sizeof(int));
|
||||
inform_ncpserv();
|
||||
return;
|
||||
|
||||
default : break;
|
||||
}
|
||||
if (bytes_to_write_to_ncpserv > 255) inform_ncpserv();
|
||||
@ -155,7 +156,7 @@ static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode)
|
||||
bind.addr.len = sizeof(ipxAddr_t);
|
||||
bind.addr.maxlen = sizeof(ipxAddr_t);
|
||||
bind.addr.buf = (char*)&my_server_adr;
|
||||
bind.qlen = 0; /* immer */
|
||||
bind.qlen = 0; /* ever */
|
||||
if (t_bind(ipx_fd, &bind, &bind) < 0){
|
||||
char sxx[200];
|
||||
sprintf(sxx,"NWSERV:t_bind !OK in open_ipx_socket, sock=%d", sock_nr);
|
||||
@ -180,14 +181,6 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
|
||||
char *progname="ncpserv";
|
||||
char addrstr[100];
|
||||
char pathname[300];
|
||||
|
||||
char gidstr[10];
|
||||
char uidstr[10];
|
||||
|
||||
char debug1[5];
|
||||
char debug2[5];
|
||||
char debug3[5];
|
||||
|
||||
int j = FD_NWSERV;
|
||||
close(fds_out[1]); /* no need to write */
|
||||
dup2(fds_out[0], 0); /* becommes stdin */
|
||||
@ -197,20 +190,9 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr)
|
||||
dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */
|
||||
close(fds_in[1]); /* no longer needed */
|
||||
while (j++ < 100) close(j); /* close all > 4 */
|
||||
|
||||
ipx_addr_to_adr(addrstr, addr);
|
||||
sprintf(gidstr, "%d", conn_gid);
|
||||
sprintf(uidstr, "%d", conn_uid);
|
||||
|
||||
sprintf(debug1, "%d", ncpserv_debug);
|
||||
sprintf(debug2, "%d", nwconn_debug);
|
||||
sprintf(debug3, "%d", ipxdebug);
|
||||
|
||||
execl(get_exec_path(pathname, progname), progname,
|
||||
nwname, addrstr,
|
||||
gidstr, uidstr,
|
||||
debug1, debug2, debug3, NULL);
|
||||
|
||||
nwname, addrstr, NULL);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
@ -250,6 +232,17 @@ static int start_nwclient(void)
|
||||
}
|
||||
|
||||
/* =========================== WDOG =============================== */
|
||||
|
||||
#ifdef _WDOG_TESTING_
|
||||
/* for testing */
|
||||
# define WDOG_TRIE_AFTER_SEC 1
|
||||
# define MAX_WDOG_TRIES 1
|
||||
#else
|
||||
# define WDOG_TRIE_AFTER_SEC 300 /* ca. 5 min. */
|
||||
# define MAX_WDOG_TRIES 11 /* Standardtries */
|
||||
#endif
|
||||
|
||||
|
||||
static void send_wdog_packet(ipxAddr_t *addr, int conn, int what)
|
||||
{
|
||||
uint8 data[2];
|
||||
@ -277,7 +270,7 @@ typedef struct {
|
||||
} CONN;
|
||||
|
||||
static CONN conns[MAX_CONNECTIONS];
|
||||
static int hi_conn=0;
|
||||
static int hi_conn=0; /* highest connection nr in use */
|
||||
|
||||
static void insert_wdog_conn(int conn, ipxAddr_t *adr)
|
||||
{
|
||||
@ -294,39 +287,41 @@ static void insert_wdog_conn(int conn, ipxAddr_t *adr)
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_wdog_conn(int conn)
|
||||
static void modify_wdog_conn(int conn, int mode)
|
||||
/* mode = 0 : reset */
|
||||
/* mode = 1 : force test 1 */
|
||||
/* mode = 2 : force test 2 */
|
||||
/* mode = 99 : remove wdog */
|
||||
{
|
||||
if (conn > 0 && --conn < hi_conn) {
|
||||
CONN *c=&(conns[conn]);
|
||||
if (mode < 99) {
|
||||
c->last_time = akttime_stamp;
|
||||
c->counter = 0;
|
||||
}
|
||||
}
|
||||
switch (mode) {
|
||||
case 1 : c->counter = MAX_WDOG_TRIES; /* quick test */
|
||||
broadsecs = 4096;
|
||||
break;
|
||||
|
||||
static void remove_wdog_conn(int conn)
|
||||
{
|
||||
if (conn > 0 && --conn < hi_conn) {
|
||||
CONN *c=&(conns[conn]);
|
||||
case 2 : c->counter = 1; /* slow test (activate)*/
|
||||
broadsecs = 4096;
|
||||
break;
|
||||
|
||||
default : c->counter = 0; /* reset */
|
||||
break;
|
||||
} /* switch */
|
||||
} else if (mode == 99) { /* remove */
|
||||
memset(c, 0, sizeof(CONN));
|
||||
if (conn + 1 == hi_conn) {
|
||||
while (hi_conn) {
|
||||
CONN *c=&(conns[hi_conn-1]);
|
||||
c=&(conns[hi_conn-1]);
|
||||
if (!c->last_time) hi_conn--;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WDOG_TESTING_
|
||||
/* for testing */
|
||||
# define WDOG_TRIE_AFTER_SEC 1
|
||||
# define MAX_WDOG_TRIES 1
|
||||
#else
|
||||
# define WDOG_TRIE_AFTER_SEC 300 /* ca. 5 min. */
|
||||
# define MAX_WDOG_TRIES 11 /* Standardtries */
|
||||
#endif
|
||||
|
||||
static void send_wdogs(void)
|
||||
{
|
||||
int k = hi_conn;
|
||||
@ -363,43 +358,6 @@ static void send_bcasts(int conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================== SERVER BROADCAST ======================== */
|
||||
static int send_broadcast(int fd, int firsttime, int down)
|
||||
/* periodic Broadcast Message */
|
||||
{
|
||||
IPX_DATA ipx_data;
|
||||
int ipx_pack_typ = 17;
|
||||
ipxAddr_t wild;
|
||||
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
U32_TO_BE32(network, wild.net);
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
memset(&ipx_data, 0, sizeof(ipx_data.sip));
|
||||
strcpy(ipx_data.sip.server_name, my_nwname);
|
||||
memcpy(&ipx_data.sip.server_adr, &my_server_adr, sizeof(ipxAddr_t));
|
||||
U16_TO_BE16(SOCK_NCP, ipx_data.sip.server_adr.sock);
|
||||
/* NCP SOCKET verwenden */
|
||||
|
||||
if (firsttime && start_ncpserv(ipx_data.sip.server_name,
|
||||
&ipx_data.sip.server_adr)) return(-1);
|
||||
|
||||
U16_TO_BE16(2, ipx_data.sip.response_type); /* General */
|
||||
U16_TO_BE16(4, ipx_data.sip.server_type); /* Fileserver */
|
||||
|
||||
if (down) {
|
||||
U16_TO_BE16(16, ipx_data.sip.intermediate_networks);
|
||||
} else {
|
||||
U16_TO_BE16(1, ipx_data.sip.intermediate_networks);
|
||||
/* I think 1 is ok here */
|
||||
}
|
||||
send_ipx_data(fd, ipx_pack_typ,
|
||||
sizeof(ipx_data.sip),
|
||||
(char *)&(ipx_data.sip),
|
||||
&wild, "SIP Broadcast");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void send_server_respons(int fd, uint8 ipx_pack_typ,
|
||||
int respond_typ, int server_typ,
|
||||
@ -426,11 +384,6 @@ void get_server_data(char *name,
|
||||
ipxAddr_t *adr,
|
||||
ipxAddr_t *from_addr)
|
||||
{
|
||||
#ifdef LINUX
|
||||
if (memcmp(adr->net, my_server_adr.net, IPX_NET_SIZE))
|
||||
/* don't add our own netroute twice */
|
||||
myipx_route_add(adr->net, from_addr->net, from_addr->node);
|
||||
#endif
|
||||
if (!nw386_found) {
|
||||
memcpy(&nw386_adr, adr, sizeof(ipxAddr_t));
|
||||
nw386_found++;
|
||||
@ -439,11 +392,11 @@ void get_server_data(char *name,
|
||||
client_mode = 0; /* only start once */
|
||||
}
|
||||
}
|
||||
DPRINTF(("NW386 %s found at:%s\n", name, visable_ipx_adr(adr)));
|
||||
XDPRINTF((2,"NW386 %s found at:%s\n", name, visable_ipx_adr(adr)));
|
||||
ins_del_bind_net_addr(name, adr);
|
||||
}
|
||||
|
||||
void handle_sap(int fd,
|
||||
static void handle_sap(int fd,
|
||||
int ipx_pack_typ,
|
||||
int data_len,
|
||||
IPX_DATA *ipxdata,
|
||||
@ -452,92 +405,47 @@ void handle_sap(int fd,
|
||||
int query_type = GET_BE16(ipxdata->sqp.query_type);
|
||||
int server_type = GET_BE16(ipxdata->sqp.server_type);
|
||||
if (query_type == 3) {
|
||||
DPRINTF(("SAP NEAREST SERVER request typ=%d von %s\n", server_type, visable_ipx_adr(from_addr)));
|
||||
XDPRINTF((2,"SAP NEAREST SERVER request typ=%d von %s\n",
|
||||
server_type, visable_ipx_adr(from_addr)));
|
||||
if (server_type == 4) {
|
||||
/* Get Nearest File Server */
|
||||
send_server_respons(fd, ipx_pack_typ,
|
||||
4, server_type, from_addr);
|
||||
send_server_respons(fd, ipx_pack_typ, 4, server_type, from_addr);
|
||||
}
|
||||
} else if (query_type == 1) { /* general Request */
|
||||
DPRINTF(("SAP GENERAL request server_type =%d\n", server_type));
|
||||
XDPRINTF((2,"SAP GENERAL request server_type =%d\n", server_type));
|
||||
if (server_type == 4) {
|
||||
/* Get General File Server Request */
|
||||
send_server_respons(fd, ipx_pack_typ,
|
||||
4, server_type, from_addr);
|
||||
send_server_respons(fd, ipx_pack_typ, 4, server_type, from_addr);
|
||||
}
|
||||
} else if (query_type == 2) { /* periodic general or shutdown response */
|
||||
DPRINTF(("SAP PERIODIC response von %s\n", visable_ipx_adr(from_addr)));
|
||||
if (server_type == 4) { /* from Fileserver */
|
||||
DPRINTF(("FROM SERVER intermediate=%d\n",
|
||||
GET_BE16(ipxdata->sip.intermediate_networks)));
|
||||
if (16 == GET_BE16(ipxdata->sip.intermediate_networks)) {
|
||||
} else if (query_type == 2 || query_type == 4) {
|
||||
/* periodic general or shutdown response (2)
|
||||
* or nearests Service Response (4)
|
||||
*/
|
||||
int entries = (data_len-2) / sizeof(SAPS);
|
||||
uint8 *p = ((uint8*)ipxdata)+2;
|
||||
XDPRINTF((2,"SAP PERIODIC (entries=%d) from %s\n", entries, visable_ipx_adr(from_addr)));
|
||||
while (entries--) {
|
||||
int type = GET_BE16(p);
|
||||
uint8 *name = p+2;
|
||||
ipxAddr_t *ad = (ipxAddr_t*) (p+50);
|
||||
int hops = GET_BE16(p+ sizeof(SAPS) -2);
|
||||
XDPRINTF((2,"TYP=%2d,hops=%2d, Addr=%s, Name=%s\n", type, hops,
|
||||
visable_ipx_adr(ad), name));
|
||||
|
||||
if (type == 4 && strcmp(name, my_nwname)) { /* from Fileserver */
|
||||
if (16 == hops) {
|
||||
/* shutdown */
|
||||
if (memcmp(ipxdata->sip.server_adr.net,
|
||||
my_server_adr.net, IPX_NET_SIZE)) {
|
||||
/* don't kill our own netroute */
|
||||
DPRINTF(("SERVER %s IS GOING DOWN\n", ipxdata->sip.server_name));
|
||||
ins_del_bind_net_addr(ipxdata->sip.server_name, NULL);
|
||||
#ifdef LINUX
|
||||
myipx_route_del(ipxdata->sip.server_adr.net);
|
||||
#endif
|
||||
XDPRINTF((2,"SERVER %s IS GOING DOWN\n", name));
|
||||
ins_del_bind_net_addr(name, NULL);
|
||||
} else {
|
||||
DPRINTF(("SHUTDOWN RESPONSE from SERVER %s\n", ipxdata->sip.server_name));
|
||||
get_server_data(name, ad, from_addr);
|
||||
}
|
||||
}
|
||||
p+=sizeof(SAPS);
|
||||
} /* while */
|
||||
} else {
|
||||
get_server_data(ipxdata->sip.server_name, &(ipxdata->sip.server_adr),
|
||||
from_addr);
|
||||
XDPRINTF((1,"UNKNOWN SAP query %x, server %x\n", query_type, server_type));
|
||||
}
|
||||
}
|
||||
} else if (query_type == 4) { /* nearests Service Response */
|
||||
DPRINTF(("SAP nearest Service response\n"));
|
||||
if (server_type == 4){
|
||||
get_server_data(ipxdata->sip.server_name, &(ipxdata->sip.server_adr),
|
||||
from_addr);
|
||||
}
|
||||
} else DPRINTF(("UNKNOWN SAP query %x, server %x\n", query_type, server_type));
|
||||
}
|
||||
|
||||
static void send_rip(ipxAddr_t *from_addr)
|
||||
{
|
||||
RIP rip;
|
||||
ipxAddr_t to_addr;
|
||||
memset(&rip, 0, sizeof(RIP));
|
||||
if (from_addr) memcpy(&to_addr, from_addr, sizeof(ipxAddr_t));
|
||||
else {
|
||||
memset(&to_addr, 0, sizeof(ipxAddr_t));
|
||||
U32_TO_BE32(network, to_addr.net);
|
||||
memset(to_addr.node, 0xFF, IPX_NODE_SIZE);
|
||||
U16_TO_BE16(SOCK_RIP, to_addr.sock);
|
||||
}
|
||||
memcpy(rip.network, my_server_adr.net, IPX_NET_SIZE);
|
||||
U16_TO_BE16(2, rip.operation); /* rip response or general */
|
||||
U16_TO_BE16(1, rip.ticks); /* on ethernets allways 1 Tick */
|
||||
U16_TO_BE16(0, rip.hops);
|
||||
send_ipx_data(sockfd[RIP_SLOT],
|
||||
1,
|
||||
sizeof(RIP),
|
||||
(char *)&rip,
|
||||
&to_addr, "SEND RIP");
|
||||
}
|
||||
|
||||
static void handle_rip(int fd, int ipx_pack_typ,
|
||||
int data_len, IPX_DATA *ipxdata,
|
||||
ipxAddr_t *from_addr)
|
||||
{
|
||||
int operation = GET_BE16(ipxdata->rip.operation);
|
||||
int hops = GET_BE16(ipxdata->rip.hops);
|
||||
int ticks = GET_BE16(ipxdata->rip.ticks);
|
||||
DPRINTF(("Rip %s hops %d, ticks %d, network:%02x.%02x.%02x.%02x\n",
|
||||
(operation == 1) ? "Request" : "Response",
|
||||
hops, ticks,
|
||||
(int)ipxdata->rip.network[0],
|
||||
(int)ipxdata->rip.network[1],
|
||||
(int)ipxdata->rip.network[2],
|
||||
(int)ipxdata->rip.network[3]));
|
||||
if (operation == 1) { /* rip request */
|
||||
send_rip(from_addr);
|
||||
} else if (operation != 2) /* NICHT RIP response */
|
||||
DPRINTF(("UNKNOWN RIP operation %d\n", operation));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -586,7 +494,7 @@ static void response_ipx_diag(int fd, int ipx_pack_typ,
|
||||
datalen++;
|
||||
*p++ = 1; /* Bridge Driver */
|
||||
datalen++;
|
||||
/* Jetzt extended */
|
||||
/* now extended */
|
||||
*p++ = 6; /* Fileserver/Bridge (internal) */
|
||||
datalen++;
|
||||
*p++ = 1; /* Anz. Networks */
|
||||
@ -620,7 +528,7 @@ static void handle_diag(int fd, int ipx_pack_typ,
|
||||
}
|
||||
exnodes += IPX_NODE_SIZE;
|
||||
}
|
||||
DPRINTF(("DIAG Request, ipx_pack_typ %d, data_len %d, count %d\n",
|
||||
XDPRINTF((2,"DIAG Request, ipx_pack_typ %d, data_len %d, count %d\n",
|
||||
(int)ipx_pack_typ, data_len, count));
|
||||
response_ipx_diag(fd, ipx_pack_typ, from_addr);
|
||||
}
|
||||
@ -658,22 +566,28 @@ static void handle_event(int fd, uint16 socknr, int slot)
|
||||
ud.addr.buf = (char*)&source_adr;
|
||||
t_rcvuderr(fd, &uderr);
|
||||
DPRINTF(("Error from %s, Code = 0x%lx\n", visable_ipx_adr(&erradr), uderr.error));
|
||||
t_error("t_rcvudata !OK");
|
||||
if (nw_debug) t_error("t_rcvudata !OK");
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTF(("Ptyp:%d von: %s\n", (int)ipx_pack_typ, visable_ipx_adr(&source_adr) ));
|
||||
XDPRINTF((3,"Ptyp:%d from: %s\n", (int)ipx_pack_typ, visable_ipx_adr(&source_adr) ));
|
||||
|
||||
if (server_down_stamp) return; /* no more interests */
|
||||
|
||||
if ( IPXCMPNODE(source_adr.node, my_server_adr.node) &&
|
||||
IPXCMPNET (source_adr.net, my_server_adr.net)) {
|
||||
|
||||
if IPXCMPNODE(source_adr.node, my_server_adr.node) {
|
||||
int source_sock = (int) GET_BE16(source_adr.sock);
|
||||
if ( source_sock == sock_nummern[MY_BROADCAST_SLOT]
|
||||
|| source_sock == sock_nummern[WDOG_SLOT]
|
||||
|| source_sock == SOCK_SAP
|
||||
|| source_sock == SOCK_RIP) {
|
||||
DPRINTF(("OWN Packet, ignored\n"));
|
||||
XDPRINTF((2,"OWN Packet from sock:0x%04x, ignored\n", source_sock));
|
||||
return;
|
||||
}
|
||||
|
||||
/* it also can be Packets from DOSEMU OR ncpfs on this machine */
|
||||
DPRINTF(("Packet from OWN maschine:sock=0x%x\n", source_sock));
|
||||
XDPRINTF((2,"Packet from OWN maschine:sock=0x%x\n", source_sock));
|
||||
}
|
||||
|
||||
switch (socknr) {
|
||||
@ -683,12 +597,12 @@ static void handle_event(int fd, uint16 socknr, int slot)
|
||||
|
||||
default :
|
||||
if (WDOG_SLOT == slot) { /* this is a watchdog packet */
|
||||
DPRINTF(("WDOG Packet len=%d connid=%d, status=%d\n",
|
||||
XDPRINTF((2,"WDOG Packet len=%d connid=%d, status=%d\n",
|
||||
(int)ud.udata.len, (int) ipx_data_buff.wdog.connid,
|
||||
(int)ipx_data_buff.wdog.status));
|
||||
if (2 == ud.udata.len) {
|
||||
if ('Y' == ipx_data_buff.wdog.status)
|
||||
reset_wdog_conn(ipx_data_buff.wdog.connid);
|
||||
modify_wdog_conn(ipx_data_buff.wdog.connid, 0);
|
||||
}
|
||||
} else {
|
||||
uint8 *p = (uint8*)&ipx_data_buff;
|
||||
@ -706,97 +620,91 @@ static void handle_event(int fd, uint16 socknr, int slot)
|
||||
}
|
||||
}
|
||||
|
||||
static void get_server(void)
|
||||
static void get_ini(int full)
|
||||
{
|
||||
if (!nw386_found) { /* no other server was found yet. */
|
||||
SQP sqp;
|
||||
ipxAddr_t wild;
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
U32_TO_BE32(network, wild.net);
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
U16_TO_BE16(3, sqp.query_type);
|
||||
U16_TO_BE16(4, sqp.server_type);
|
||||
send_ipx_data(sockfd[SAP_SLOT], 17, sizeof(SQP),
|
||||
(char*)&sqp, &wild, "SERVER Query");
|
||||
}
|
||||
}
|
||||
|
||||
static void get_ini(void)
|
||||
{
|
||||
FILE *f=open_nw_ini();
|
||||
char *frname=NULL;
|
||||
#ifdef LINUX
|
||||
strcpy(devname, "eth0"); /* default */
|
||||
#endif
|
||||
FILE *f = open_nw_ini();
|
||||
int k;
|
||||
uint32 node = 1; /* default 1 */
|
||||
if (full) {
|
||||
gethostname(my_nwname, 48);
|
||||
upstr(my_nwname);
|
||||
}
|
||||
if (f){
|
||||
char buff[500];
|
||||
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)))) {
|
||||
char inhalt[500];
|
||||
char inhalt2[500];
|
||||
char inhalt3[500];
|
||||
char inhalt4[500];
|
||||
char dummy;
|
||||
int anz;
|
||||
if ((anz=sscanf((char*)buff, "%s %s %s", inhalt, inhalt2, inhalt3)) > 0) {
|
||||
if ((anz=sscanf((char*)buff, "%s %s %s", inhalt, inhalt2,
|
||||
inhalt3, inhalt4)) > 0) {
|
||||
switch (what) {
|
||||
case 2 : strncpy(my_nwname, inhalt, 48);
|
||||
case 2 : if (full) {
|
||||
strncpy(my_nwname, inhalt, 48);
|
||||
my_nwname[47] = '\0';
|
||||
upstr(my_nwname);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef LINUX
|
||||
case 3 :
|
||||
if (full) {
|
||||
if (sscanf(inhalt, "%ld%c", &internal_net, &dummy) != 1)
|
||||
sscanf(inhalt, "%lx", &internal_net);
|
||||
if (anz > 1) {
|
||||
if (sscanf(inhalt2, "%ld%c", &node, &dummy) != 1)
|
||||
sscanf(inhalt2, "%lx", &node);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 4 :
|
||||
if (sscanf(inhalt, "%ld%c", &network, &dummy) != 1)
|
||||
sscanf(inhalt, "%lx", &network);
|
||||
#ifdef LINUX
|
||||
if (anz > 1) {
|
||||
strncpy(devname, inhalt2, sizeof(devname));
|
||||
devname[sizeof(devname)-1] = '\0';
|
||||
}
|
||||
if (full) {
|
||||
if (anz_net_devices < MAX_NET_DEVICES &&
|
||||
(!anz_net_devices || anz > 2) ) {
|
||||
NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]);
|
||||
NW_NET_DEVICE *nd=*pnd=
|
||||
(NW_NET_DEVICE*)xmalloc(sizeof(NW_NET_DEVICE));
|
||||
memset(nd, 0, sizeof(NW_NET_DEVICE));
|
||||
nd->ticks = 1;
|
||||
nd->frame = IPX_FRAME_8023;
|
||||
new_str(nd->devname, "eth0");
|
||||
|
||||
if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1)
|
||||
sscanf(inhalt, "%lx", &nd->net);
|
||||
if (anz > 1)
|
||||
new_str(nd->devname, inhalt2);
|
||||
|
||||
if (anz > 2) {
|
||||
upstr(inhalt3);
|
||||
if (!strcmp(inhalt3, "802.3")) frame=IPX_FRAME_8023;
|
||||
if (!strcmp(inhalt3, "802.3"))
|
||||
nd->frame=IPX_FRAME_8023;
|
||||
else if (!strcmp(inhalt3, "802.2"))
|
||||
frame=IPX_FRAME_8022;
|
||||
nd->frame=IPX_FRAME_8022;
|
||||
else if (!strcmp(inhalt3, "SNAP"))
|
||||
frame=IPX_FRAME_SNAP;
|
||||
nd->frame=IPX_FRAME_SNAP;
|
||||
else if (!strcmp(inhalt3, "ETHERNET_II"))
|
||||
frame=IPX_FRAME_ETHERII;
|
||||
nd->frame=IPX_FRAME_ETHERII;
|
||||
}
|
||||
if (anz > 3) nd->ticks = atoi(inhalt4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifdef LINUX
|
||||
case 5 : save_ipx_routes=atoi(inhalt);
|
||||
break;
|
||||
#endif
|
||||
case 104 : /* nwclient */
|
||||
if (client_mode && atoi(inhalt))
|
||||
client_mode++;
|
||||
break;
|
||||
|
||||
case 10 :
|
||||
sscanf(inhalt, "%d", &conn_gid);
|
||||
break;
|
||||
|
||||
case 11 :
|
||||
sscanf(inhalt, "%d", &conn_uid);
|
||||
break;
|
||||
|
||||
case 100 :
|
||||
sscanf(inhalt, "%d", &ipxdebug);
|
||||
break;
|
||||
|
||||
case 101 :
|
||||
sscanf(inhalt, "%d", &nw_debug);
|
||||
break;
|
||||
|
||||
case 102 :
|
||||
sscanf(inhalt, "%d", &ncpserv_debug);
|
||||
break;
|
||||
|
||||
case 103 :
|
||||
sscanf(inhalt, "%d", &nwconn_debug);
|
||||
case 210 : server_goes_down_secs=atoi(inhalt);
|
||||
if (server_goes_down_secs < 1 ||
|
||||
server_goes_down_secs > 600)
|
||||
server_goes_down_secs = 10;
|
||||
break;
|
||||
|
||||
default : break;
|
||||
@ -805,77 +713,122 @@ static void get_ini(void)
|
||||
} /* while */
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (client_mode < 2) client_mode=0;
|
||||
if (full) {
|
||||
#ifdef LINUX
|
||||
switch (frame) {
|
||||
init_ipx(internal_net, node, ipxdebug);
|
||||
for (k=0; k < anz_net_devices; k++){
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
char *frname=NULL;
|
||||
switch (nd->frame) {
|
||||
case IPX_FRAME_8022 : frname = "802.2"; break;
|
||||
case IPX_FRAME_8023 : frname = "802.3"; break;
|
||||
case IPX_FRAME_SNAP : frname = "SNAP"; break;
|
||||
case IPX_FRAME_ETHERII : frname = "ETHERNET_II";break;
|
||||
default : break;
|
||||
} /* switch */
|
||||
#else
|
||||
frname = "ETHERNET_II";
|
||||
#endif
|
||||
fprintf(stdout,
|
||||
"Servername='%s', NETWORK='0x%lx', NODE='0x%lx'\n",
|
||||
my_nwname, network, internal_net);
|
||||
|
||||
#ifdef LINUX
|
||||
fprintf(stdout, "Device=%s, Frame=%s\n", devname, frname);
|
||||
init_ipx(devname, &network, internal_net, frame, frname, ipxdebug);
|
||||
fprintf(stdout, "NETWORK is=0x%lx\n", network);
|
||||
DPRINTF(("DEVICE=%s, FRAME=%s, NETWORK=0x%lx\n",
|
||||
nd->devname, frname, nd->net));
|
||||
init_dev(nd->devname, nd->frame, nd->net);
|
||||
}
|
||||
#endif
|
||||
if (!get_ipx_addr(&my_server_adr)) {
|
||||
internal_net = GET_BE32(my_server_adr.net);
|
||||
} else exit(1);
|
||||
DPRINTF(("Servername='%s', INTERNAL NET=0x%lx, NODE=0x%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
my_nwname, internal_net,
|
||||
(int)my_server_adr.node[0],
|
||||
(int)my_server_adr.node[1],
|
||||
(int)my_server_adr.node[2],
|
||||
(int)my_server_adr.node[3],
|
||||
(int)my_server_adr.node[4],
|
||||
(int)my_server_adr.node[5]));
|
||||
} /* if full */
|
||||
}
|
||||
|
||||
static void send_down_broadcast(void)
|
||||
{
|
||||
int j = 20;
|
||||
while (j--) send_broadcast(sockfd[MY_BROADCAST_SLOT], 0, 1);
|
||||
send_sap_broadcast(2);
|
||||
send_rip_broadcast(2); /* shutdown rip */
|
||||
}
|
||||
|
||||
static void close_all(void)
|
||||
{
|
||||
int j = NEEDED_SOCKETS;
|
||||
if (pid_ncpserv > 0) {
|
||||
if (fd_ncpserv_out > -1) close(fd_ncpserv_out);
|
||||
if (fd_ncpserv_in > -1) close(fd_ncpserv_in);
|
||||
kill(pid_ncpserv, SIGTERM); /* terminate ncpserv */
|
||||
kill(pid_ncpserv, SIGKILL); /* kill ncpserv */
|
||||
}
|
||||
|
||||
while (j--) {
|
||||
t_unbind(sockfd[j]);
|
||||
t_close(sockfd[j]);
|
||||
}
|
||||
|
||||
if (pid_ncpserv > 0) {
|
||||
int status;
|
||||
if (fd_ncpserv_out > -1) {
|
||||
close(fd_ncpserv_out);
|
||||
fd_ncpserv_out =-1;
|
||||
}
|
||||
if (fd_ncpserv_in > -1) {
|
||||
close(fd_ncpserv_in);
|
||||
fd_ncpserv_in = -1;
|
||||
}
|
||||
kill(pid_ncpserv, SIGTERM); /* terminate ncpserv */
|
||||
waitpid(pid_ncpserv, &status, 0);
|
||||
kill(pid_ncpserv, SIGKILL); /* kill ncpserv */
|
||||
}
|
||||
|
||||
#ifdef LINUX
|
||||
fprintf(stdout, "Close Device=%s\n", devname);
|
||||
exit_ipx(devname, network, frame);
|
||||
if (!save_ipx_routes) {
|
||||
for (j=0; j<anz_net_devices;j++) {
|
||||
NW_NET_DEVICE *nd=net_devices[j];
|
||||
DPRINTF(("Close Device=%s, frame=%d\n",
|
||||
nd->devname, nd->frame));
|
||||
exit_dev(nd->devname, nd->frame);
|
||||
}
|
||||
}
|
||||
exit_ipx(!save_ipx_routes);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void sig_quit(int rsig)
|
||||
static void down_server(void)
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
if (!server_down_stamp) {
|
||||
write_to_ncpserv(0xffff, 0, NULL, 0);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
fprintf(stderr, "\007");
|
||||
fprintf(stderr, "\n*********************************************\n");
|
||||
fprintf(stderr, "\nWARNING: NWE-SERVER shuts down in %3d sec !!!\n",
|
||||
server_goes_down_secs);
|
||||
fprintf(stderr, "\n*********************************************\n");
|
||||
sleep(1);
|
||||
fprintf(stderr, "\007\n");
|
||||
broadsecs=100;
|
||||
server_down_stamp = akttime_stamp;
|
||||
send_down_broadcast();
|
||||
close_all();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int fl_get_debug=0;
|
||||
static void get_new_debug(void)
|
||||
static int fl_get_int=0;
|
||||
static void sig_quit(int rsig)
|
||||
{
|
||||
get_ini_debug(1);
|
||||
fl_get_debug=0;
|
||||
signal(rsig, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN); /* don't want it anymore */
|
||||
fl_get_int=2;
|
||||
}
|
||||
|
||||
static void handle_hup_reqest(void)
|
||||
{
|
||||
get_ini_debug(NWSERV);
|
||||
XDPRINTF((2, "NWSERV:Got HUP, reading ini.\n"));
|
||||
get_ini(0);
|
||||
write_to_ncpserv(0xeeee, 0, NULL, 0); /* inform ncpserv */
|
||||
fl_get_int=0;
|
||||
}
|
||||
|
||||
static void sig_hup(int rsig)
|
||||
{
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
fl_get_debug++;
|
||||
fl_get_int=1;
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
@ -892,10 +845,11 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int j = -1;
|
||||
tzset();
|
||||
if (argc > 1) client_mode++;
|
||||
if (argc > 1) client_mode=1;
|
||||
/* in client mode the testprog 'nwclient' will be startet. */
|
||||
|
||||
get_ini();
|
||||
init_tools(NWSERV);
|
||||
get_ini(1);
|
||||
|
||||
while (++j < NEEDED_POLLS) {
|
||||
polls[j].events = POLLIN|POLLPRI;
|
||||
@ -917,72 +871,79 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!send_broadcast(sockfd[MY_BROADCAST_SLOT], 1, 0)) {
|
||||
U16_TO_BE16(SOCK_NCP, my_server_adr.sock);
|
||||
if (!start_ncpserv(my_nwname, &my_server_adr)) {
|
||||
/* Jetzt POLLEN */
|
||||
|
||||
time_t broadtime;
|
||||
time(&broadtime);
|
||||
set_sigs();
|
||||
|
||||
polls[NEEDED_SOCKETS].fd = fd_ncpserv_in;
|
||||
|
||||
while (1) {
|
||||
int anz_poll = poll(polls, NEEDED_POLLS,
|
||||
(!client_mode) ? 30000 : 15000);
|
||||
|
||||
if (fl_get_debug) get_new_debug();
|
||||
|
||||
int anz_poll = poll(polls, NEEDED_POLLS, broadsecs);
|
||||
time(&akttime_stamp);
|
||||
if (fl_get_int) {
|
||||
if (fl_get_int == 1) handle_hup_reqest();
|
||||
else if (fl_get_int == 2) down_server();
|
||||
}
|
||||
if (anz_poll > 0) { /* i have to work */
|
||||
struct pollfd *p = &polls[0];
|
||||
j = -1;
|
||||
while (++j < NEEDED_POLLS) {
|
||||
if (p->revents){
|
||||
if (j < NEEDED_SOCKETS) { /* socket */
|
||||
/*
|
||||
DPRINTF(("POLL %d, SOCKET %x, ", p->revents, sock_nummern[j]));
|
||||
*/
|
||||
if (p->revents & ~POLLIN) perror("STREAM error");
|
||||
XDPRINTF((99,"POLL %d, SOCKET %x, ", p->revents, sock_nummern[j]));
|
||||
if (p->revents & ~POLLIN)
|
||||
errorp(0, "STREAM error", "revents=0x%x", p->revents );
|
||||
else handle_event(p->fd, sock_nummern[j], j);
|
||||
} else { /* fd_ncpserv_in */
|
||||
DPRINTF(("POLL %d, fh=%d\n", p->revents, p->fd));
|
||||
if (p->revents & ~POLLIN) perror("STREAM error");
|
||||
XDPRINTF((2,"POLL %d, fh=%d\n", p->revents, p->fd));
|
||||
if (p->revents & ~POLLIN)
|
||||
errorp(0, "STREAM error", "revents=0x%x", p->revents );
|
||||
else {
|
||||
if (p->fd == fd_ncpserv_in) {
|
||||
int what;
|
||||
int conn;
|
||||
int size;
|
||||
ipxAddr_t adr;
|
||||
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&what, sizeof(int))) {
|
||||
DPRINTF(("GOT ncpserv_in what=0x%x\n", what));
|
||||
XDPRINTF((2,"GOT ncpserv_in what=0x%x\n", what));
|
||||
switch (what) {
|
||||
case 0x2222 : /* insert wdog connection */
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&conn, sizeof(int))
|
||||
&& sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&size, sizeof(int))
|
||||
&& sizeof(ipxAddr_t) == read(fd_ncpserv_in,
|
||||
(char*)&adr, sizeof(ipxAddr_t)))
|
||||
(char*)&adr, size))
|
||||
insert_wdog_conn(conn, &adr);
|
||||
break;
|
||||
|
||||
case 0x4444 : /* reset wdog connection */
|
||||
case 0x4444 : /* reset wdog connection = 0 */
|
||||
/* force test wdog conn 1 = 1 */
|
||||
/* force test wdog conn 2 = 2 */
|
||||
/* remove wdog = 99 */
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&conn, sizeof(int)))
|
||||
reset_wdog_conn(conn);
|
||||
(char*)&conn, sizeof(int))
|
||||
&& sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&what, sizeof(what)))
|
||||
modify_wdog_conn(conn, what);
|
||||
break;
|
||||
|
||||
case 0x6666 : /* remove wdog connection */
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&conn, sizeof(int)))
|
||||
remove_wdog_conn(conn);
|
||||
break;
|
||||
|
||||
case 0x8888 : /* bcast message */
|
||||
case 0x6666 : /* bcast message */
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&conn, sizeof(int)))
|
||||
send_bcasts(conn);
|
||||
break;
|
||||
|
||||
case 0xffff : /* down file server */
|
||||
if (sizeof(int) == read(fd_ncpserv_in,
|
||||
(char*)&conn, sizeof(int)) &&
|
||||
conn == what) {
|
||||
down_server();
|
||||
}
|
||||
break;
|
||||
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
@ -994,21 +955,31 @@ int main(int argc, char **argv)
|
||||
p++;
|
||||
} /* while */
|
||||
} else {
|
||||
/* if (anz_poll < 0) perror("POLL error"); */
|
||||
if (nw_debug > 2) DPRINTF(("POLLING ...\n"));
|
||||
XDPRINTF((99,"POLLING ...\n"));
|
||||
}
|
||||
if (server_down_stamp) {
|
||||
if (akttime_stamp - server_down_stamp > server_goes_down_secs) break;
|
||||
} else {
|
||||
if (akttime_stamp - broadtime > (broadsecs / 1000)) { /* ca. 60 seconds */
|
||||
send_sap_broadcast(broadsecs<3000); /* firsttime broadcast */
|
||||
send_rip_broadcast(broadsecs<3000); /* firsttime broadcast */
|
||||
if (broadsecs < 32000) {
|
||||
rip_for_net(MAX_U32);
|
||||
get_servers();
|
||||
broadsecs *= 2;
|
||||
}
|
||||
if (akttime_stamp - broadtime > 59) { /* ca. 60 seconds */
|
||||
send_wdogs();
|
||||
send_broadcast(sockfd[MY_BROADCAST_SLOT], 0, 0);
|
||||
send_rip(NULL);
|
||||
get_server();
|
||||
inform_ncpserv();
|
||||
send_wdogs();
|
||||
broadtime = akttime_stamp;
|
||||
} else if (client_mode) get_server(); /* Here more often */
|
||||
} else if (client_mode) get_servers(); /* Here more often */
|
||||
}
|
||||
} /* while */
|
||||
send_down_broadcast();
|
||||
sleep(1);
|
||||
send_down_broadcast();
|
||||
}
|
||||
close_all();
|
||||
fprintf(stderr, "\nNWE-SERVER is down now !!\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
58
nwserv.h
Normal file
58
nwserv.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* nwserv.h 09-Dec-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.
|
||||
*/
|
||||
|
||||
extern uint32 internal_net; /* NETWORKNUMMER INTERN (SERVER) */
|
||||
extern ipxAddr_t my_server_adr; /* Address of this server */
|
||||
extern char my_nwname[50]; /* Name of this server */
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *devname; /* "eth0" or "isdnX" */
|
||||
int frame; /* frametyp */
|
||||
int ticks; /* ether:ticks=1, isdn:ticks=7 */
|
||||
uint32 net; /* NETWORK NUMBER */
|
||||
} NW_NET_DEVICE;
|
||||
|
||||
/* <========== DEVICES ==========> */
|
||||
extern int anz_net_devices;
|
||||
extern NW_NET_DEVICE *net_devices[];
|
||||
|
||||
/* <======== SOCKETS =========> */
|
||||
#define MY_BROADCAST_SLOT 0 /* Server Broadcast OUT */
|
||||
#define WDOG_SLOT 1 /* Watchdog send + recv */
|
||||
|
||||
#define SAP_SLOT 2
|
||||
#define RIP_SLOT 3
|
||||
#define ROUTE_SLOT 4
|
||||
#define DIAG_SLOT 5
|
||||
#if 0
|
||||
#define ECHO_SLOT 6
|
||||
#define ERR_SLOT 7
|
||||
#endif
|
||||
|
||||
extern int sockfd[];
|
||||
|
||||
extern void send_rip_broadcast(int mode);
|
||||
extern void send_sap_broadcast(int mode);
|
||||
extern void rip_for_net(uint32 net);
|
||||
extern void get_servers(void);
|
||||
|
||||
extern void handle_rip(int fd, int ipx_pack_typ,
|
||||
int data_len, IPX_DATA *ipxdata,
|
||||
ipxAddr_t *from_addr);
|
||||
|
109
tools.c
109
tools.c
@ -1,4 +1,4 @@
|
||||
/* tools.c 18-Nov-95 */
|
||||
/* tools.c 06-Dec-95 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -21,12 +21,13 @@
|
||||
#include <sys/vfs.h>
|
||||
|
||||
int nw_debug=0;
|
||||
FILE *logfile=stdout;
|
||||
|
||||
char *xmalloc(uint size)
|
||||
{
|
||||
char *p = (size) ? (char *)malloc(size) : (char*)NULL;
|
||||
if (p == (char *)NULL && size){
|
||||
fprintf(stderr, "not enough core, need %d Bytes\n", size);
|
||||
fprintf(logfile, "not enough core, need %d Bytes\n", size);
|
||||
exit(1);
|
||||
}
|
||||
return(p);
|
||||
@ -63,9 +64,9 @@ void dprintf(char *p, ...)
|
||||
va_list ap;
|
||||
if (nw_debug){
|
||||
va_start(ap, p);
|
||||
vprintf(p, ap);
|
||||
vfprintf(logfile, p, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,22 +75,39 @@ void xdprintf(int dlevel, char *p, ...)
|
||||
va_list ap;
|
||||
if (nw_debug >= dlevel) {
|
||||
va_start(ap, p);
|
||||
vprintf(p, ap);
|
||||
vfprintf(logfile, p, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
void errorp(int mode, char *what, char *p, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int errnum = errno;
|
||||
if (errnum >= 0 && errnum < _sys_nerr)
|
||||
fprintf(logfile, "%s:%s\n", what, _sys_errlist[errnum]);
|
||||
else
|
||||
fprintf(logfile, "%s:errno=%d\n", what, errnum);
|
||||
if (p) {
|
||||
va_start(ap, p);
|
||||
vfprintf(logfile, p, ap);
|
||||
va_end(ap);
|
||||
fprintf(logfile, "\n");
|
||||
}
|
||||
fflush(logfile);
|
||||
}
|
||||
|
||||
FILE *open_nw_ini(void)
|
||||
{
|
||||
char *fname=FILENAME_NW_INI;
|
||||
FILE *f=fopen(fname, "r");
|
||||
if (f == (FILE*)NULL) fprintf(stderr, "Cannot open ini file `%s`\n", fname);
|
||||
if (f == (FILE*)NULL) fprintf(logfile, "Cannot open ini file `%s`\n", fname);
|
||||
return(f);
|
||||
}
|
||||
|
||||
int get_ini_entry(FILE *f, int entry, char *str, int strsize)
|
||||
/* liefert ini_entry zurueck bzw. 0, falls nichts gefunden */
|
||||
/* returns ini_entry or 0 if nothing found */
|
||||
{
|
||||
char buff[512];
|
||||
int do_open = ((FILE*) NULL == f);
|
||||
@ -98,6 +116,7 @@ int get_ini_entry(FILE *f, int entry, char *str, int strsize)
|
||||
while (fgets((char*)buff, sizeof(buff), f) != NULL){
|
||||
int len = strlen(buff);
|
||||
char *ppi = NULL;
|
||||
char *ppe = NULL;
|
||||
int se = 0;
|
||||
int j = -1;
|
||||
while (++j < len){
|
||||
@ -108,8 +127,9 @@ int get_ini_entry(FILE *f, int entry, char *str, int strsize)
|
||||
break;
|
||||
} else if ( *pp == 32 || *pp == '\t') {
|
||||
if (!se) se = j;
|
||||
} else if ((!ppi) && se) {
|
||||
ppi = pp;
|
||||
} else {
|
||||
if ((!ppi) && se) ppi = pp;
|
||||
ppe=pp;
|
||||
}
|
||||
}
|
||||
if (len > se+1 && se > 0 && se < 4 && ppi){
|
||||
@ -118,6 +138,7 @@ int get_ini_entry(FILE *f, int entry, char *str, int strsize)
|
||||
strmaxcpy(sx, buff, se);
|
||||
fentry = atoi(sx);
|
||||
if (fentry > 0 && ((!entry) || entry == fentry)) {
|
||||
if (ppe) *(ppe+1) = '\0';
|
||||
strmaxcpy(str, ppi, strsize-1);
|
||||
if (do_open) fclose(f);
|
||||
return(fentry);
|
||||
@ -135,18 +156,71 @@ char *get_exec_path(char *buff, char *progname)
|
||||
return(buff);
|
||||
}
|
||||
|
||||
int get_ini_int(int what)
|
||||
{
|
||||
char buff[30];
|
||||
int i;
|
||||
if (get_ini_entry(NULL, what, buff, sizeof(buff))
|
||||
&& 1==sscanf(buff, "%d", &i) ) return(i);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void get_ini_debug(int what)
|
||||
void get_ini_debug(int module)
|
||||
/* what:
|
||||
* 1 = nwserv
|
||||
* 2 = ncpserv
|
||||
* 3 = nwconn
|
||||
*/
|
||||
{
|
||||
char buff[10];
|
||||
if (get_ini_entry(NULL, 100+what, buff, sizeof(buff))) {
|
||||
int debug;
|
||||
if (1==sscanf(buff, "%d", &debug)) nw_debug=debug;
|
||||
int debug = get_ini_int(100+module);
|
||||
if (debug > -1) nw_debug = debug;
|
||||
}
|
||||
|
||||
void init_tools(int module)
|
||||
{
|
||||
char buff[300];
|
||||
char logfilename[300];
|
||||
FILE *f=open_nw_ini();
|
||||
int withlog=0;
|
||||
int dodaemon=0;
|
||||
int new_log=0;
|
||||
if (f) {
|
||||
int what;
|
||||
while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { /* daemonize */
|
||||
if (200 == what) dodaemon = atoi(buff);
|
||||
else if (201 == what) {
|
||||
strmaxcpy(logfilename, buff, sizeof(logfilename)-1);
|
||||
withlog++;
|
||||
} else if (202 == what) {
|
||||
new_log = atoi(buff);
|
||||
} else if (100+module == what) nw_debug=atoi(buff);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
if (dodaemon) {
|
||||
if (!withlog) strcpy(logfilename, "./nw.log");
|
||||
if (NWSERV == module) { /* now make daemon */
|
||||
int fd=fork();
|
||||
if (fd) exit((fd > 0) ? 0 : 1);
|
||||
}
|
||||
if (NULL == (logfile = fopen(logfilename,
|
||||
(new_log && NWSERV == module) ? "w" : "a"))) {
|
||||
char sxx[100];
|
||||
sprintf(sxx, "\n\nOpen logfile `%s`", logfilename);
|
||||
perror(sxx);
|
||||
logfile = stdout;
|
||||
fprintf(stderr, "\n!! ABORTED !!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (NWSERV == module) setsid();
|
||||
}
|
||||
}
|
||||
|
||||
void exit_tools(int what)
|
||||
{
|
||||
if (logfile != stdout) {
|
||||
if (logfile != NULL) fclose(logfile);
|
||||
logfile=stdout;
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,11 +273,14 @@ static long adjust_blocks (long blocks, int fromsize, int tosize)
|
||||
return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize);
|
||||
}
|
||||
|
||||
|
||||
int get_fs_usage(char *path, struct fs_usage *fsp)
|
||||
{
|
||||
struct statfs fsd;
|
||||
if (statfs (path, &fsd) < 0) return (-1);
|
||||
XDPRINTF((2,
|
||||
"blocks=%d, bfree=%d, bavail=%d, files=%d, ffree=%d, bsize=%d\n",
|
||||
fsd.f_blocks, fsd.f_bfree, fsd.f_bavail,
|
||||
fsd.f_files, fsd.f_ffree, fsd.f_bsize));
|
||||
#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512)
|
||||
fsp->fsu_blocks = convert_blocks (fsd.f_blocks);
|
||||
fsp->fsu_bfree = convert_blocks (fsd.f_bfree);
|
||||
|
9
tools.h
9
tools.h
@ -17,6 +17,12 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Prozesse die tools verwenden */
|
||||
#define NWSERV 1
|
||||
#define NCPSERV 2
|
||||
#define NWCONN 3
|
||||
|
||||
extern FILE *logfile;
|
||||
extern void x_x_xfree(char **p);
|
||||
extern int x_x_xnewstr(uint8 **p, uint8 *s);
|
||||
|
||||
@ -27,10 +33,13 @@ extern char *xmalloc(uint size);
|
||||
extern int strmaxcpy(char *dest, char *source, int len);
|
||||
extern void dprintf(char *p, ...);
|
||||
extern void xdprintf(int dlevel, char *p, ...);
|
||||
extern void errorp(int mode, char *what, char *p, ...);
|
||||
extern FILE *open_nw_ini(void);
|
||||
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 uint8 down_char(uint8 ch);
|
||||
extern uint8 up_char(uint8 ch);
|
||||
|
Loading…
Reference in New Issue
Block a user