mars_nwe-0.98.pl09
This commit is contained in:
parent
519bf6bfcd
commit
178789c7e4
3
Makefile
3
Makefile
@ -53,6 +53,9 @@ distrib_bin: mk.li nw.ini
|
||||
diff:
|
||||
./mk.li $@
|
||||
|
||||
showconf:
|
||||
./mk.li -s $@
|
||||
|
||||
mk.li: examples/mk.li
|
||||
@if [ -r $@ ] ; then \
|
||||
cp -f $@ $@.org && ( \
|
||||
|
@ -1224,7 +1224,7 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len,
|
||||
}
|
||||
if (completition < 0) return(completition);
|
||||
strcpy(unname, build_unix_name(&nwpath, 2));
|
||||
XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", unname));
|
||||
XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", access, unname));
|
||||
if (!stat(unname, &stbuff)){
|
||||
int result = chmod(unname, un_nw_attrib(&stbuff, access, 1));
|
||||
return( (result != 0) ? -0x8c : 0); /* no modify rights */
|
||||
@ -1473,7 +1473,7 @@ int nw_init_connect(void)
|
||||
} else if (what == 11) { /* UID */
|
||||
default_uid = atoi((char*)buff);
|
||||
} else if (what == 103) { /* Debug */
|
||||
nw_debug = atoi((char*)buff);
|
||||
get_debug_level(buff);
|
||||
}
|
||||
} /* while */
|
||||
nw_init_volumes(f);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* debmask.h: 30-Dec-96 */
|
||||
/* debmask.h: 15-Feb-97 */
|
||||
#ifndef _DEBMASK_H_
|
||||
#define _DEBMASK_H_
|
||||
/*
|
||||
@ -10,6 +10,7 @@
|
||||
/* NWCONN */
|
||||
#define D_FH_OPEN 1 /* file open/close */
|
||||
#define D_FH_LOCK 2 /* file lock/unlock */
|
||||
#define D_FH_FLUSH 4 /* file flushes */
|
||||
|
||||
|
||||
#endif
|
||||
|
5
doc/BUGS
5
doc/BUGS
@ -27,6 +27,11 @@ some short notes for problem- or bug-reports.
|
||||
linux-kernel, 2.0.23
|
||||
exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. )
|
||||
changes you made into nwserv.conf(nw.ini), config.h.
|
||||
- if you send nwserv.conf, please remove the comments first.
|
||||
A simple way would be:
|
||||
'make showconf' in the mars_nwserv directory or do a
|
||||
'grep "^[ \t]*[0-9]" /etc/nwserv.conf'
|
||||
|
||||
- report whether your client runs correct under a 'real Novell-Server'.
|
||||
( if you have one ;) )
|
||||
|
||||
|
15
doc/CHANGES
15
doc/CHANGES
@ -1,6 +1,6 @@
|
||||
Sorry, this is in German only.
|
||||
User important notes are in the NEWS file.
|
||||
Aenderungen in mars_nwe bis zum : 17-Jan-97
|
||||
Aenderungen in mars_nwe bis zum : 16-Apr-97
|
||||
--------------------------------
|
||||
Erste 'oeffentliche' Version
|
||||
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
|
||||
@ -273,4 +273,17 @@ Erste 'oeffentliche' Version
|
||||
- Print Queue Command Parameter erweitert um '!'
|
||||
fuer banner_user_name, banner_file_name
|
||||
<----- ^^^^^^^^^^ pl8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- Dateimatchroutine OS/2 namespace wiederum abgeaendert.
|
||||
Es wurde z.B. bei x.* auch xyz.* gematched.
|
||||
- Funktion 0x16,ufunc 0x28 implementiert.
|
||||
Wurde von ndir 4.x benoetigt.
|
||||
- Syntax und Handling automatisch erzeugter/erkannter IPX-Interfaces
|
||||
geaendert. Es wird nun unterschieden zwischen kernel auto creat
|
||||
und Erkennung innerhalb mars_nwe. Section 4 + 5 abgeaendert.
|
||||
Vorschlag/Tip von Morio Taneda.
|
||||
- neuer Aufrufparameter 'nwserv -u' fuer update internal Routes/Devices.
|
||||
- Byte Ordering bei Filehandles umgedreht. Dadurch sollen
|
||||
nach Tests von Arne de Bruijn Probleme mit Netx beseitigt sein.
|
||||
- Section 13 erweitert um 'fixed passwords'.
|
||||
<----- ^^^^^^^^^^ pl9 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -10,6 +10,9 @@ Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
|
||||
Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
|
||||
many testings+notes
|
||||
|
||||
Arne de Bruijn <arne@arne.bilt>
|
||||
testings, exploring ncp mysterius (netx), notes
|
||||
|
||||
Hardy Buchholz <hardy@kool.f.eunet.de>
|
||||
wrote HOWTO.ger
|
||||
|
||||
@ -40,6 +43,9 @@ Jiri A. Randus <Jiri.Randus@vslib.cz>
|
||||
Gregory Steuck <greg@nsu.ru>
|
||||
testings and errorreports
|
||||
|
||||
Morio Taneda <eb04@rz.uni-karlsruhe.de>
|
||||
testings, bugfixes
|
||||
|
||||
Erik Thiele <erik@escape.mos.unterland.de>
|
||||
testings and doc
|
||||
|
||||
|
23
doc/FAQS
23
doc/FAQS
@ -1,4 +1,4 @@
|
||||
last updated: 16-Jan-97
|
||||
last updated: 11-Apr-97
|
||||
Q: I don't exaclty understand the meaning of some ponits in nw.ini:
|
||||
12,13
|
||||
What will happen if I will not put PASSWORD here? Will it take it from
|
||||
@ -51,5 +51,26 @@ A: Sorry but mars_nwe can recognize this setting only at compile time,
|
||||
so you must compile mars_nwe again with actual kernel CONFIG_IPX_INTERN=NO
|
||||
settings.
|
||||
|
||||
Q: What is an easy way to get a 'clean' nwserv.conf file without comments.
|
||||
A: do a 'make showconf' in the mars_nwserv directory or do a
|
||||
'grep "^[ \t]*[0-9]" /etc/nwserv.conf'
|
||||
|
||||
Q: Which frametyp should I use (Ethernet_ii, 802.2, SNAP or 802.3) ?
|
||||
A: Use Ethernet_II on a new network as it can carry anything and everything
|
||||
(AFAIK) and doesn't have any of the potential disadvantages of the rest.
|
||||
|
||||
If you're trying to fit into an already established environment which
|
||||
doesn't use Ethernet II for IPX/SPX traffic then try using 802.2 if
|
||||
available. Netware v4 upwards uses this by default. Apparently OSI uses
|
||||
this as well.
|
||||
|
||||
I'll gloss over SNAP at this point, as I only know of it being used
|
||||
in Appletalk environments which I've never dealt with. I did just notice
|
||||
a comment in the Linux source tree about not using it for IP and IPX yet(?).
|
||||
|
||||
Last, and pretty much least, comes 802.3 which is only used by IPX/SPX,
|
||||
and for less and less of that these days, but it shouldn't break anything
|
||||
if you have to use it.
|
||||
(Rick)
|
||||
|
||||
|
||||
|
10
doc/INSTALL
10
doc/INSTALL
@ -11,9 +11,7 @@ the mars_nwe-package.
|
||||
|
||||
For general questions about how to compile a kernel,
|
||||
please see the Linux Kernel-HOWTO.
|
||||
Best kernels for mars_nwe are 1.3.57
|
||||
(with little patch from example directory)
|
||||
or kernels >= 1.3.60.
|
||||
Best kernels for mars_nwe are 2.0.x.
|
||||
Older kernels will sometimes not work because of
|
||||
bugs in the ipx-code. See examples directory for
|
||||
some patches.
|
||||
@ -42,7 +40,8 @@ the mars_nwe-package.
|
||||
You request this with the following entries in `nwserv.conf':
|
||||
|
||||
3 0x0 # use your IP number for internal net.
|
||||
4 0x0 * AUTO # autocreat Interfaces
|
||||
4 0x0 * AUTO # autodetect interfaces.
|
||||
5 0x2 # set kernel autocreat interfaces = on.
|
||||
|
||||
Make sure that no other server is using your internal net number
|
||||
as it's networknumber.
|
||||
@ -110,6 +109,9 @@ the mars_nwe-package.
|
||||
into the "LOGIN" or "login" directory.
|
||||
You also can use the free mars_dosutils with a poor version of
|
||||
these programms.
|
||||
NEW !
|
||||
In newer versions of mars_nwe these directories will be created
|
||||
after the first start of mars_nwe.
|
||||
|
||||
(7) Fire it up
|
||||
|
||||
|
@ -20,11 +20,12 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
|
||||
Eintrag '3' der 'ini/conf Datei' muss eine im Netz eindeutige
|
||||
Netwerknummer erhalten.
|
||||
Es muss ein Eintrag '4' mit Netzwerk Nummer = 0,
|
||||
Device = '*' und Frame = 'auto' fuer ein 'autocreat' Interface
|
||||
Device = '*' und Frame = 'auto' fuer ein 'autodetect' Interface
|
||||
vorhanden sein.
|
||||
Beispiel fuer conf/ini Datei: (siehe auch: examples/nw.ini)
|
||||
3 0x77777 # eindeutige Netzwerk Nummer fuer internal net.
|
||||
4 0x0 * AUTO # autocreat Interfaces
|
||||
3 0x0 # verwende IP Nummer als Internal Net.
|
||||
4 0x0 * AUTO # autodetect interfaces.
|
||||
5 0x2 # set kernel autocreat interfaces = on.
|
||||
|
||||
Falls kein anderer IPX/NCP Server im Netz vorhanden ist
|
||||
kann im Eintrag '4' eine beliebige Netzwerknummer verwendet werden.
|
||||
@ -33,6 +34,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
|
||||
4 0x20 eth0 802.3 # eth0 Device mit Netznummer '0x20'
|
||||
# und Frame ETHERNET_802.3.
|
||||
|
||||
|
||||
2. Mars_nwe soll nur als File Server Verwendung finden, d.h.
|
||||
Routing usw. soll von anderen Programmen erledigt werden.
|
||||
-> Die IPX-Interfaces muessen durch andere Programme/Tools
|
||||
@ -41,6 +43,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
|
||||
In mars_nwe/config.h muss folgende Zeile vorhanden sein.
|
||||
#define INTERNAL_RIP_SAP 0
|
||||
|
||||
|
||||
=========> Programme erzeugen
|
||||
1. make aufrufen.
|
||||
2. mk.li und config.h evtl. anpassen
|
||||
@ -59,7 +62,7 @@ zu *ueberschreiben* .
|
||||
|
||||
=========> Starten
|
||||
nwserv starten ( als root !! )
|
||||
mit Linux Version 1.2.13 und 1.3.32 getestet.
|
||||
mit Linux Version 1.2.13 und 1.3.32 und 2.0.x 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
|
||||
|
6
doc/NEWS
6
doc/NEWS
@ -1,4 +1,8 @@
|
||||
# in this files are some notes for user of mars_nwe.
|
||||
------17-Apr-97--- 0.98.pl9 ----------
|
||||
- Section 4: IPX-Devices, syntax of automatic creation of interfaces and
|
||||
- Section 5: save flag -> device flags CHANGED !!
|
||||
- 'nwserv -u' for updating internal routes/devices.
|
||||
- Section 13: new switch: 'fixed passwords'.
|
||||
------29-Jan-97--- 0.98.pl8 ----------
|
||||
- Section 6: version-"spoofing" now set to '1' (3.11) default.
|
||||
- New switch in config.h: QUOTA_SUPPORT
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
mars_nwe - Martin Stovers netware emulation
|
||||
Copyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
Copyright (C) 1993,1997 Martin Stover, Marburg, Germany
|
||||
|
||||
|
||||
Help on how to compile and install can be found in `INSTALL'.
|
||||
@ -8,7 +8,7 @@ Help on how to compile and install can be found in `INSTALL'.
|
||||
|
||||
"mars_nwe" is an attempt to emulate the basic functionality
|
||||
of a netware-server under UNIX (Linux).
|
||||
The first version was written 1993 on a USL1.1 with TLI-Code.
|
||||
The first version was written 1993 on a UnixWare 1.1 with TLI-Code.
|
||||
1994 I ported it to LINUX, which was easy because I only had
|
||||
to write a small TLI->SOCKET emulation (see the modul
|
||||
"emutli").
|
||||
|
@ -1,10 +1,10 @@
|
||||
(C)opyright (C) 1993,1996 Martin Stover, Marburg
|
||||
(C)opyright (C) 1993,1997 Martin Stover, Marburg
|
||||
|
||||
Hilfe zum Kompilieren bzw. Installieren siehe in 'INSTALL' !
|
||||
|
||||
Dieses ist ein kleiner Versuch Grundfunktionen
|
||||
eines Novell Servers unter UNIX (LINUX) zur Verfuegung
|
||||
zu stellen. Die erste Version entstand 1993 auf einer USL1.1
|
||||
zu stellen. Die erste Version entstand 1993 auf einer UnixWare 1.1
|
||||
mittels TLI-Code und wurde 1994, mittels
|
||||
dem modul 'emutli' (TLI -> SOCKETS) nach Linux portiert.
|
||||
|
||||
@ -55,8 +55,6 @@ PROBLEME bzw. TODO's:
|
||||
Vieles :-(
|
||||
Hier nur eine *kleine* Auswahl.
|
||||
|
||||
o - Passwortaenderungen durch Client ermoeglichen.
|
||||
o - Routing verbessern.
|
||||
o - Drucken verbessern.
|
||||
o - Saeubern !!
|
||||
o - Bindery Code vervollstaendigen.
|
||||
|
@ -1,7 +1,7 @@
|
||||
Begin3
|
||||
Title: mars_nwe
|
||||
Version: 0.98.pl8
|
||||
Entered-date: 01-Feb-97
|
||||
Version: 0.98.pl9
|
||||
Entered-date: 18-Apr-97
|
||||
Description: Full netware-emulator (src), beta.
|
||||
Supports file-services, bindery-services,
|
||||
printing-services, routing-services.
|
||||
@ -9,8 +9,8 @@ Keywords: novell, netware, server, ipx, ncp, tli
|
||||
Author: mstover@stover.f.eunet.de (Martin Stover)
|
||||
Maintained-by: mstover@stover.f.eunet.de (Martin Stover)
|
||||
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
|
||||
200kB mars_nwe-0.98.pl8.tgz
|
||||
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
|
||||
200kB mars_nwe-0.98.pl9.tgz
|
||||
Alternate-site: sunsite.unc.edu:/pub/Linux/system/filesystems/ncpfs
|
||||
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
|
||||
Copying-policy: GNU
|
||||
End
|
||||
|
4
emutli.c
4
emutli.c
@ -187,7 +187,7 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
|
||||
return(result);
|
||||
}
|
||||
|
||||
int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
|
||||
inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
|
||||
{
|
||||
struct sockaddr_ipx ipxs;
|
||||
int sz = sizeof(struct sockaddr_ipx);
|
||||
@ -224,7 +224,7 @@ static void sig_alarm(int rsig)
|
||||
#endif
|
||||
|
||||
|
||||
int t_sndudata(int fd, struct t_unitdata *ud)
|
||||
inline int t_sndudata(int fd, struct t_unitdata *ud)
|
||||
{
|
||||
int result;
|
||||
struct sockaddr_ipx ipxs;
|
||||
|
5
emutli.h
5
emutli.h
@ -102,10 +102,9 @@ extern int t_bind(int sock, struct t_bind *a_in, struct t_bind *a_out);
|
||||
extern int t_unbind(int sock);
|
||||
extern void t_error(char *s);
|
||||
extern int t_close(int fd);
|
||||
extern int t_rcvudata(int fd, struct t_unitdata *ud, int *flags);
|
||||
extern inline 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 inline int t_sndudata(int fd, struct t_unitdata *ud);
|
||||
|
||||
#ifndef IPX_FRAME_8022
|
||||
# define OLD_KERNEL_IPX 1
|
||||
|
95
emutli1.c
95
emutli1.c
@ -1,4 +1,4 @@
|
||||
/* emutli1.c 24-Jun-96 */
|
||||
/* emutli1.c 10-Apr-97 */
|
||||
/*
|
||||
* One short try to emulate TLI with SOCKETS.
|
||||
*/
|
||||
@ -61,10 +61,10 @@ static int x_ioctl(int sock, int mode, void *id)
|
||||
int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
|
||||
int *flags, uint8 *name)
|
||||
|
||||
/* returns frame or if error < 0 */
|
||||
/* returns frame or -1 for no frame or -2 for error */
|
||||
{
|
||||
uint32 snet;
|
||||
int frame=-1;
|
||||
int frame =-2;
|
||||
int xflags = 0;
|
||||
uint8 buff1[200];
|
||||
uint8 buff2[200];
|
||||
@ -76,7 +76,7 @@ int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
|
||||
if (sscanf(data, "%lx %s %s %s %s",
|
||||
rnet, buff1, buff2, buff3, buff4) == 5 ) {
|
||||
int len = strlen(buff4);
|
||||
if (!len) return(-1);
|
||||
if (!len) return(-2);
|
||||
switch (*(buff4+len-1)) {
|
||||
case '2' : frame = IPX_FRAME_8022; break;
|
||||
case '3' : frame = IPX_FRAME_8023; break;
|
||||
@ -85,6 +85,8 @@ int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
|
||||
#ifdef IPX_FRAME_TR_8022
|
||||
case 'R' : frame = IPX_FRAME_TR_8022; break;
|
||||
#endif
|
||||
case 'e' :
|
||||
case 'E' : frame = -1; break; /* NONE */
|
||||
default : return(-2);
|
||||
}
|
||||
if (node) strmaxcpy(node, buff1, 12);
|
||||
@ -95,9 +97,8 @@ int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
|
||||
|
||||
if (name) strmaxcpy(name, buff3, 20);
|
||||
upstr(buff3);
|
||||
if (!strcmp(buff2, "INTERNAL")) /* internal net */
|
||||
if (!strcmp(buff3, "INTERNAL")) /* internal net */
|
||||
*flags |= 2;
|
||||
|
||||
}
|
||||
return(frame);
|
||||
}
|
||||
@ -169,6 +170,47 @@ static void del_special_net(int special, char *devname, int frame)
|
||||
}
|
||||
}
|
||||
|
||||
static void del_all_interfaces_nets(void)
|
||||
/* removes all ipx_interfaces */
|
||||
{
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock > -1) {
|
||||
FILE *f=fopen("/proc/net/ipx_interface", "r");
|
||||
if (f) {
|
||||
char buff[200];
|
||||
uint8 name[25];
|
||||
struct ifreq id;
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
|
||||
while (fgets((char*)buff, sizeof(buff), f) != NULL){
|
||||
int flags = 0;
|
||||
int frame = read_interface_data((uint8*) buff, NULL, NULL,
|
||||
&flags, name);
|
||||
if (frame < -1) continue;
|
||||
|
||||
memset(&id, 0, sizeof(struct ifreq));
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
|
||||
if (flags & 2) { /* internal */
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
} else {
|
||||
sipx->sipx_type = frame;
|
||||
strcpy(id.ifr_name, name);
|
||||
if (flags & 1) /* primary */
|
||||
sipx->sipx_special = IPX_PRIMARY;
|
||||
else
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
}
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
x_ioctl(sock, SIOCSIFADDR, &id);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
|
||||
#define del_internal_net() \
|
||||
del_special_net(IPX_INTERNAL, NULL, 0)
|
||||
#define del_interface(devname, frame) \
|
||||
@ -230,7 +272,7 @@ int get_frame_name(uint8 *framename, int frame)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int init_ipx(uint32 network, uint32 node, int ipx_debug)
|
||||
int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags)
|
||||
{
|
||||
int result=-1;
|
||||
int sock;
|
||||
@ -243,6 +285,7 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug)
|
||||
exit(1);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if ((sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0) {
|
||||
errorp(1, "EMUTLI:init_ipx", NULL);
|
||||
errorp(10, "Problem", "probably kernel-IPX is not setup correctly");
|
||||
@ -254,6 +297,7 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug)
|
||||
auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces;
|
||||
set_sock_debug(sock);
|
||||
result=0;
|
||||
|
||||
/* build new internal net */
|
||||
if (network) {
|
||||
struct sockaddr_ipx ipxs;
|
||||
@ -272,50 +316,47 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug)
|
||||
add_internal_net(network, node);
|
||||
have_ipx_started++;
|
||||
}
|
||||
|
||||
if ((flags & 2) && !auto_interfaces) { /* set auto interfaces */
|
||||
auto_interfaces = 1;
|
||||
ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
void exit_ipx(int full)
|
||||
void exit_ipx(int flags)
|
||||
{
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock > -1) {
|
||||
/* Switch DEBUG off */
|
||||
set_locipxdebug(0);
|
||||
set_sock_debug(sock);
|
||||
#if 1
|
||||
if (have_ipx_started && full) org_auto_interfaces = 0;
|
||||
#endif
|
||||
if (have_ipx_started && !(flags&1))
|
||||
org_auto_interfaces = 0;
|
||||
if (auto_interfaces != org_auto_interfaces)
|
||||
ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces);
|
||||
close(sock);
|
||||
}
|
||||
if (have_ipx_started && full) del_internal_net();
|
||||
if (have_ipx_started && !(flags&1)) {
|
||||
del_all_interfaces_nets();
|
||||
}
|
||||
}
|
||||
|
||||
int init_dev(char *devname, int frame, uint32 network)
|
||||
int init_dev(char *devname, int frame, uint32 network, int wildmask)
|
||||
{
|
||||
int is_auto = (!network || frame < 0 || devname[0] == '*');
|
||||
if (frame > -1 && devname[0] != '*') del_interface(devname, frame);
|
||||
if (!(wildmask & 3))
|
||||
del_interface(devname, frame);
|
||||
if (!have_ipx_started) {
|
||||
if (is_auto) return(-99);
|
||||
if (wildmask) return(-99);
|
||||
have_ipx_started++;
|
||||
del_primary_net();
|
||||
add_primary_net(devname, frame, network);
|
||||
} else {
|
||||
if (!is_auto)
|
||||
if (!wildmask)
|
||||
return(add_device_net(devname, frame, network));
|
||||
else if (!auto_interfaces) {
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (sock < 0) return(-2);
|
||||
auto_interfaces = 1;
|
||||
if (ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces) < 0) {
|
||||
close(sock);
|
||||
return(-3);
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* emutli1.h 24-Jun-96 */
|
||||
/* emutli1.h 10-Apr-97 */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -28,9 +28,9 @@ extern int read_interface_data(uint8* data, uint32 *rnet, uint8 *node,
|
||||
extern int get_interface_frame_name(char *name, uint32 net);
|
||||
|
||||
extern int get_frame_name(uint8 *framename, int frame);
|
||||
extern int init_ipx(uint32 network, uint32 node, int ipx_debug);
|
||||
extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags);
|
||||
extern void exit_ipx(int full);
|
||||
extern int init_dev(char *devname, int frame, uint32 network);
|
||||
extern int init_dev(char *devname, int frame, uint32 network, int wildmask);
|
||||
extern void exit_dev(char *devname, int frame);
|
||||
|
||||
#if 0
|
||||
|
66
examples/kpatch2.0.28
Normal file
66
examples/kpatch2.0.28
Normal file
@ -0,0 +1,66 @@
|
||||
diff -uwr linux-2.0.28/include/linux/ipx.h linux/include/linux/ipx.h
|
||||
--- linux-2.0.28/include/linux/ipx.h Mon May 13 22:39:28 1996
|
||||
+++ linux/include/linux/ipx.h Tue Jan 14 16:33:27 1997
|
||||
@@ -75,5 +75,6 @@
|
||||
#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
|
||||
#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1)
|
||||
#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2)
|
||||
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3)
|
||||
#endif
|
||||
|
||||
diff -uwr linux-2.0.28/include/net/sock.h linux/include/net/sock.h
|
||||
--- linux-2.0.28/include/net/sock.h Sun Dec 1 19:01:21 1996
|
||||
+++ linux/include/net/sock.h Tue Jan 14 16:34:39 1997
|
||||
@@ -112,6 +112,10 @@
|
||||
* know the connection this socket belongs to.
|
||||
*/
|
||||
struct ncp_server *ncp_server;
|
||||
+/*
|
||||
+ * To handle special NCP-Sockets for mars_nwe
|
||||
+ */
|
||||
+ unsigned short ipx_ncp_conn;
|
||||
|
||||
};
|
||||
#endif
|
||||
diff -uwr linux-2.0.28/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
|
||||
--- linux-2.0.28/net/ipx/af_ipx.c Wed Nov 27 08:44:21 1996
|
||||
+++ linux/net/ipx/af_ipx.c Tue Jan 14 16:33:27 1997
|
||||
@@ -468,6 +468,20 @@
|
||||
ipx_socket *sock1 = NULL, *sock2 = NULL;
|
||||
struct sk_buff *skb1 = NULL, *skb2 = NULL;
|
||||
|
||||
+ if (intrfc == ipx_primary_net
|
||||
+ && ntohs(ipx->ipx_dest.sock) == 0x451
|
||||
+ && *((char*)(ipx+1)) == 0x22
|
||||
+ && *((char*)(ipx+1)+1) == 0x22) {
|
||||
+ int connection = (int) *((char*)(ipx+1)+3);
|
||||
+ /* 255 connections are enough ;) */
|
||||
+ if (connection) {
|
||||
+ for (sock1=intrfc->if_sklist;
|
||||
+ (sock1 != NULL) &&
|
||||
+ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
|
||||
+ sock1=sock1->next);;
|
||||
+ }
|
||||
+ }
|
||||
+ if (sock1 == NULL)
|
||||
sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
|
||||
|
||||
/*
|
||||
@@ -2242,6 +2256,17 @@
|
||||
if(err) return err;
|
||||
return(ipxcfg_get_config_data((void *)arg));
|
||||
}
|
||||
+
|
||||
+ case SIOCIPXNCPCONN:
|
||||
+ {
|
||||
+ if (!suser()) return(-EPERM);
|
||||
+ err = verify_area(VERIFY_READ, (void *)arg,
|
||||
+ sizeof(unsigned short));
|
||||
+ if (err) return err;
|
||||
+ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
case SIOCGSTAMP:
|
||||
if (sk)
|
||||
{
|
@ -2,8 +2,9 @@
|
||||
# This is the configuration-file for "mars_nwe", a free netware-emulator
|
||||
# for Linux.
|
||||
#
|
||||
# last changed: 29-Jan-97
|
||||
|
||||
# last changed: 10-Apr-97
|
||||
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
|
||||
#
|
||||
# This file specifies which Linux-resources (printers, users, directories)
|
||||
# should be accessible to the DOS-clients via "mars_nwe". Furthermore
|
||||
# some general parameters are configured here.
|
||||
@ -85,7 +86,7 @@
|
||||
# See `doc/PIPE-FS'.
|
||||
#
|
||||
# additional Namespaces
|
||||
# O + OS/2 namespace.
|
||||
# O + OS/2 namespace (useful for Win95 clients, see doc/FAQS).
|
||||
# N + NFS namespace.
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
@ -167,7 +168,7 @@
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Example:
|
||||
# 3 auto 1 # automatic setup
|
||||
# 3 auto 1 # 'automatic' setup, use ip-number as internal net
|
||||
|
||||
3 auto
|
||||
|
||||
@ -186,22 +187,21 @@
|
||||
# - make sure your network-number is not already in use by another
|
||||
# server (see the output of "slist" under Linux or DOS)
|
||||
#
|
||||
# Under Linux, it is possible to let the kernel detect all values
|
||||
# Under Linux, it is possible to let the kernel creat all ipx-devices
|
||||
# automatically for you. This is only possible (and only makes sense then)
|
||||
# if there are other IXP/NCP servers on the same net which are setup
|
||||
# correctly.
|
||||
#
|
||||
#
|
||||
# correctly. It can be switched on in section '5'.
|
||||
# -------------------------------------------------------------------------
|
||||
# Syntax:
|
||||
# 4 NET_NUMBER DEVICE FRAME TICKS
|
||||
# 4 NET_NUMBER DEVICE FRAME [TICKS]
|
||||
#
|
||||
# NET_NUMBER: this number is determined by the router of the physical
|
||||
# network you're attached to. Use "0x0" to let the
|
||||
# linux-kernel determine your network number by listening
|
||||
# on the local network
|
||||
# network you're attached to. Use "0x0" to use the entry
|
||||
# for all network number match.
|
||||
#
|
||||
# DEVICE: the network-interface associated with the NET_NUMBER. Use
|
||||
# a "*" (star) to automatically setup all devices at once.
|
||||
# a "*" (star) to use this entry for all devices match.
|
||||
#
|
||||
# FRAME: the frame-type of the data-packets on your local network.
|
||||
# Possible values are:
|
||||
# ethernet_ii
|
||||
@ -211,40 +211,49 @@
|
||||
# token
|
||||
# auto automatic detection of the frame-type used
|
||||
# in your ipx-environment
|
||||
#
|
||||
# TICKS: the time data-packets need to get delivered over a
|
||||
# certain interface. If your connection goes through several
|
||||
# routers, the shortest path can be determined by summing up
|
||||
# all ticks for every route and compare the results.
|
||||
# (1 tick = 1/18th second)
|
||||
# (1 tick = 1/18th second), default=1
|
||||
# !! NOTE !!
|
||||
# Automatic detection in this section means that ipx-interfaces which
|
||||
# are created by other instances than the server/router,
|
||||
# e.g. pppd or ipx_interface, will be detected and inserted/removed
|
||||
# in internal device/routing table at runtime.
|
||||
#
|
||||
# Automatic kernel creation of interfaces can be switched on in section 5.
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Examples:
|
||||
# 4 0x0 * AUTO 1 # automatic setup
|
||||
# 4 0x10 eth0 802.3 1 # manual setup
|
||||
# 4 0x10 eth0 802.3 1 # setup ethernet with frame 802.3
|
||||
# 4 0xa20 arc0 802.3 1 # standard arcnet (TRXNET)
|
||||
#
|
||||
# 4 0x0 * AUTO 1 # auto detection of all ipx-interfaces.
|
||||
# 4 0x0 eth0 AUTO 1 # auto detection of eth0 frames.
|
||||
# 4 0x0 eth0 802.2 1 # auto detection of eth0 frame 802.2.
|
||||
|
||||
4 0x10 eth0 802.3 1
|
||||
4 0x22 eth0 ethernet_ii 1
|
||||
4 0x0 * AUTO 1
|
||||
|
||||
|
||||
# Section 5: special device flags
|
||||
# =========================================================================
|
||||
# Section 5: Saving of ipx-routes (required)
|
||||
# Flags
|
||||
# 0x1 do not remove routes and ipx-devices
|
||||
# beyond the lifetime of the server or router.
|
||||
# If this flag is not set then all ipx-devices/routes
|
||||
# will be deleted when nwserv/nwrouted ends (default).
|
||||
#
|
||||
# This entry controls if the information regarding the ipx-routes and
|
||||
# devices should be saved beyond the lifetime of the server.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
# Syntax:
|
||||
# 5 SAVE_FLAG
|
||||
#
|
||||
# SAVE_FLAG:
|
||||
# 0 don't save routes (default)
|
||||
# 1 do save routes
|
||||
# -------------------------------------------------------------------------
|
||||
# 0x2 Switch on automatic kernel creation of ipx-interfaces.
|
||||
# The automatic kernel creating of ipx-devices sometimes
|
||||
# make trouble (Win95). It should only be used in the
|
||||
# beginning or for testing.
|
||||
#
|
||||
# other flags may follow.
|
||||
# value will be interpreted as hex value.
|
||||
|
||||
5 0
|
||||
|
||||
5 0x0
|
||||
|
||||
# =========================================================================
|
||||
# Section 6: version-"spoofing"
|
||||
@ -434,12 +443,22 @@
|
||||
# typo), the user will only have the minimal rights defined in
|
||||
# sections 10/11.
|
||||
#
|
||||
# You may also map different mars_nwe user to the same unix user.
|
||||
#
|
||||
# See section 12 for a description of the syntax.
|
||||
#
|
||||
# Unlike in section 12, you can define users with no password.
|
||||
# -------------------------------------------------------------------------
|
||||
# Syntax:
|
||||
# 13 NW_LOGIN LINUX_LOGIN [PASSWORD] [FLAGS]
|
||||
#
|
||||
# FLAGS must be a hex value begin with 0x
|
||||
# the only FLAG value in the moment is 0x1 for 'fixed passwords'
|
||||
# which cannot be changed by user.
|
||||
# Example:
|
||||
# 13 MARTIN martin
|
||||
# 13 DAREK martin
|
||||
# 13 COMMON common gast 0x1 # no password change by user.
|
||||
|
||||
|
||||
# Section 14: currently not used
|
||||
|
14
makefile.unx
14
makefile.unx
@ -9,7 +9,7 @@ C=.c
|
||||
|
||||
V_H=0
|
||||
V_L=98
|
||||
P_L=8
|
||||
P_L=9
|
||||
|
||||
#define D_P_L 1
|
||||
DISTRIB=mars_nwe
|
||||
@ -23,7 +23,7 @@ PATCHF=$(DISTRIBF).pl$(P_L)
|
||||
#endif
|
||||
STERN=*
|
||||
|
||||
MAKEPATCH=diff -rub
|
||||
MAKEPATCH=diff -rub --new-file
|
||||
|
||||
DESTMAKEFILE=Makefile.o
|
||||
#if 0
|
||||
@ -51,6 +51,9 @@ install_ini: $(DESTMAKEFILE)
|
||||
diff: $(DESTMAKEFILE)
|
||||
$(MAKE) -f $(DESTMAKEFILE) n_$@
|
||||
|
||||
showconf: $(DESTMAKEFILE)
|
||||
$(MAKE) -f $(DESTMAKEFILE) n_$@
|
||||
|
||||
distrib: $(DESTMAKEFILE)
|
||||
$(MAKE) -f $(DESTMAKEFILE) n_$@
|
||||
|
||||
@ -170,7 +173,7 @@ $(C)$(O):
|
||||
n_all: $(PROGS)
|
||||
@echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes
|
||||
@echo "please take a look into doc/NEWS !" >> $(VPATH)/.mk.notes
|
||||
|
||||
@-head -n 5 $(VPATH)/doc/NEWS >> $(VPATH)/.mk.notes
|
||||
|
||||
n_routed: $(PROG7)
|
||||
|
||||
@ -271,4 +274,9 @@ n_distrib_bin:
|
||||
doc \
|
||||
; cd $(OBJDIR))
|
||||
|
||||
n_showconf:
|
||||
echo "#" $(M_FILENAME_NW_INI)
|
||||
grep "^[ \t]*[0-9]" $(M_FILENAME_NW_INI)
|
||||
|
||||
|
||||
|
||||
|
@ -198,8 +198,8 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
|
||||
|
||||
switch (pc) {
|
||||
case '.' :
|
||||
case 1000: if ( (*p!= 0xff || (*(p+1) != '*' && *(p+1) != 0xaa))
|
||||
&& *s && ('.' != *s++) ) return(0);
|
||||
case 1000: if (*s && ('.' != *s++))
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case '?' :
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* namspace.c 09-Nov-96 : NameSpace Services, mars_nwe */
|
||||
/* namspace.c 16-Apr-97 : NameSpace Services, mars_nwe */
|
||||
|
||||
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */
|
||||
/* Its still very dirty, but it should work fairly well */
|
||||
@ -532,8 +532,9 @@ static int insert_get_base_entry(N_NW_PATH *nwpath,
|
||||
&& nwpath->volume == e->nwpath.volume
|
||||
&& nwpath->statb.st_ino == e->nwpath.statb.st_ino
|
||||
&& nwpath->statb.st_dev == e->nwpath.statb.st_dev) {
|
||||
if (nwp_stat(&(e->nwpath), "insert_get_base_entry")) {
|
||||
/* the path has changed, we say handle is wrong */
|
||||
if (nwp_stat(&(e->nwpath), "insert_get_base_entry")
|
||||
|| strcmp(e->nwpath.path, nwpath->path)) {
|
||||
/* the path has changed, we remove this entry */
|
||||
free_dbe_p(e);
|
||||
} else {
|
||||
return(touch_handle_entry_p(e));
|
||||
@ -1270,7 +1271,7 @@ static int nw_open_creat_file_or_dir(
|
||||
(exist > -1) result=-0x84;
|
||||
|
||||
if (result > -1) {
|
||||
U32_TO_BE32(fhandle, responsedata);
|
||||
U32_TO_32(fhandle, responsedata);
|
||||
responsedata += 4;
|
||||
*responsedata =(uint8) actionresult;
|
||||
*(responsedata+1) = 0;
|
||||
|
31
net1.c
31
net1.c
@ -1,4 +1,4 @@
|
||||
/* net1.c, 26-Oct-96 */
|
||||
/* net1.c, 11-Mar-97 */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -266,7 +266,6 @@ int send_own_data(int fd, IPX_DATA *d, ipxAddr_t *toaddr)
|
||||
/* returns < 0 if senderror or functionresultcode > = 0 */
|
||||
{
|
||||
static int lastsequence=0;
|
||||
int result = -1;
|
||||
int tries = 0;
|
||||
int sendsize = d->owndata.d.size+sizeof(d->owndata.d.size)+
|
||||
sizeof(d->owndata.h);
|
||||
@ -275,32 +274,28 @@ static int lastsequence=0;
|
||||
d->owndata.h.sequence = (uint8) ++lastsequence;
|
||||
d->owndata.h.reserved = 0;
|
||||
|
||||
while (tries++ < MAX_SEND_TRIES && result < 0) {
|
||||
result=send_ipx_data(fd, 17, sendsize, (char*)d,
|
||||
toaddr, "send_own_data");
|
||||
|
||||
if (result > -1) {
|
||||
while (tries++ < MAX_SEND_TRIES) {
|
||||
int result=send_ipx_data(fd, 17, sendsize, (char*)d,
|
||||
toaddr, "send_own_data");
|
||||
while (result > -1) {
|
||||
int packet_typ;
|
||||
IPX_DATA ipxd;
|
||||
ipxAddr_t fromaddr;
|
||||
result=receive_ipx_data(fd, &packet_typ, &ipxd, &fromaddr,
|
||||
MAX_WAIT_MSEC);
|
||||
result=receive_ipx_data(fd, &packet_typ, &ipxd, &fromaddr,MAX_WAIT_MSEC);
|
||||
XDPRINTF((2, 0, "receive_ipx_data, result=%d, typ=0x%x%x, sequence=%d",
|
||||
result,
|
||||
(int)ipxd.ownreply.type[0],
|
||||
(int)ipxd.ownreply.type[1],
|
||||
(int)ipxd.ownreply.sequence ));
|
||||
if (sizeof(OWN_REPLY) == result &&
|
||||
ipxd.ownreply.type[0] == 0xef &&
|
||||
ipxd.ownreply.type[1] == 0xef &&
|
||||
/* !memcmp(&fromaddr, toaddr, sizeof(ipxAddr_t)) && */
|
||||
ipxd.ownreply.sequence == d->owndata.h.sequence) {
|
||||
result = (int)ipxd.ownreply.result;
|
||||
} else
|
||||
result=-1;
|
||||
}
|
||||
if (sizeof(OWN_REPLY) == result
|
||||
&& ipxd.ownreply.type[0] == 0xef
|
||||
&& ipxd.ownreply.type[1] == 0xef
|
||||
&& ipxd.ownreply.sequence == d->owndata.h.sequence)
|
||||
return((int)ipxd.ownreply.result);
|
||||
} /* while */
|
||||
return(result);
|
||||
} /* while */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr)
|
||||
|
9
nwbind.c
9
nwbind.c
@ -1,5 +1,5 @@
|
||||
/* nwbind.c */
|
||||
#define REVISION_DATE "20-Jan-97"
|
||||
#define REVISION_DATE "17-Apr-97"
|
||||
/* NCP Bindery SUB-SERVER */
|
||||
/* authentification and some message handling */
|
||||
|
||||
@ -878,7 +878,9 @@ static void handle_fxx(int gelen, int func)
|
||||
|
||||
internal_act = 1;
|
||||
if (act_c->object_id == 1 ||
|
||||
0 == (result=nw_test_unenpasswd(obj.id, oldpassword))){
|
||||
(0 == (result=test_allow_password_change(act_c->object_id))
|
||||
&&
|
||||
0 == (result=nw_test_unenpasswd(obj.id, oldpassword)))){
|
||||
if ( (act_c->object_id != 1)
|
||||
|| *newpassword
|
||||
|| !(password_scheme & PW_SCHEME_LOGIN))
|
||||
@ -1054,6 +1056,9 @@ static void handle_fxx(int gelen, int func)
|
||||
p += (*p+1); /* here is crypted password length */
|
||||
if (0 == (result = find_obj_id(&obj))) {
|
||||
internal_act=1;
|
||||
if (obj.id != 1)
|
||||
result=test_allow_password_change(obj.id);
|
||||
if (!result)
|
||||
result=nw_keychange_passwd(obj.id, act_c->crypt_key,
|
||||
rdata, (int)*p, p+1, act_c->object_id);
|
||||
if (!result) test_ins_unx_user(obj.id);
|
||||
|
101
nwconn.c
101
nwconn.c
@ -1,4 +1,4 @@
|
||||
/* nwconn.c 17-Jan-97 */
|
||||
/* nwconn.c 16-Apr-97 */
|
||||
/* one process / connection */
|
||||
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
@ -588,6 +588,27 @@ static int handle_ncp_serv(void)
|
||||
/* TODO !!!!!!!!!!!!!!!!!!!! */
|
||||
#endif
|
||||
do_druck++;
|
||||
} else if (*p == 0x28){
|
||||
/* Scan File Physical ??? */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 div[3]; /* 0x0, dlen, ufunc */
|
||||
uint8 dir_handle; /* directory handle */
|
||||
uint8 attrib; /* Search Attrib ?? 0x2f */
|
||||
uint8 searchsequence[4]; /* 32 bit */
|
||||
uint8 len;
|
||||
uint8 data[2];
|
||||
} *input = (struct INPUT *) (ncprequest);
|
||||
/* we try, whether this is ok ????? */
|
||||
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 == 0x29){
|
||||
/* read volume restrictions for an object */
|
||||
#if QUOTA_SUPPORT
|
||||
@ -859,7 +880,7 @@ static int handle_ncp_serv(void)
|
||||
uint8 size[4];
|
||||
uint8 weisnicht[2]; /* lock timeout ??? */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
int fhandle = GET_BE32 (input->fhandle);
|
||||
int fhandle = GET_32 (input->fhandle);
|
||||
int offset = GET_BE32(input->offset);
|
||||
int size = GET_BE32(input->size);
|
||||
completition = (uint8)(-nw_lock_datei(fhandle,
|
||||
@ -884,48 +905,30 @@ static int handle_ncp_serv(void)
|
||||
if (!ufunc) completition=0; /* TTS not availible */
|
||||
else completition=0xfb; /* request not known */
|
||||
} break;
|
||||
|
||||
case 0x23 : { /* div AFP Calls */
|
||||
#if 0
|
||||
this was wrong, I think
|
||||
case 0x3d : { /* commit file, flush file buffers */
|
||||
0x3d seems to be no valid/used NCP call.
|
||||
int ufunc = (int) *requestdata;
|
||||
#endif
|
||||
case 0x3d : /* looks also like commit file */
|
||||
/* I make no errorresult here */
|
||||
completition=0xbf; /* we say invalid namespace here */
|
||||
} break;
|
||||
|
||||
case 0x3b : /* commit file to disk */
|
||||
case 0x3d : /* commit file */
|
||||
{
|
||||
#if 0
|
||||
XDPRINTF((2,0, "don't know function: 0x3d"));
|
||||
#else
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 reserve;
|
||||
uint8 ext_fhandle[2]; /* all zero */
|
||||
uint8 fhandle[4]; /* filehandle */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
char fname[200];
|
||||
int fd = (int) GET_BE32(input->fhandle);
|
||||
int result=fd_2_fname(fd, fname, sizeof(fname));
|
||||
XDPRINTF((1,0, "0x3d, fd=%d, fn=`%s`, r=%d",
|
||||
fd, fname, result));
|
||||
#endif
|
||||
uint32 fhandle = GET_32(input->fhandle);
|
||||
int result=nw_commit_file(fhandle);
|
||||
if (result<0)
|
||||
completition=(uint8)-result;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3b :
|
||||
#if DO_DEBUG
|
||||
{ /* commit file, flush file buffers */
|
||||
struct INPUT {
|
||||
uint8 header[7]; /* Requestheader */
|
||||
uint8 reserve;
|
||||
uint8 ext_fhandle[2]; /* all zero */
|
||||
uint8 fhandle[4]; /* filehandle */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
uint32 fhandle = GET_BE32(input->fhandle);
|
||||
XDPRINTF((5,0, "should be done some time: COMMIT FILE:fhandle=%ld", fhandle));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
case 0x3e : { /* FILE SEARCH INIT */
|
||||
/* returns dhandle for searchings */
|
||||
int dir_handle = (int)*requestdata;
|
||||
@ -1052,7 +1055,7 @@ static int handle_ncp_serv(void)
|
||||
0x1, 0, (int)(ncprequest->task));
|
||||
|
||||
if (fhandle > -1){
|
||||
U32_TO_BE32(fhandle, xdata->fhandle);
|
||||
U32_TO_32(fhandle, xdata->fhandle);
|
||||
U16_TO_BE16(0, xdata->ext_fhandle);
|
||||
U16_TO_BE16(0, xdata->reserve2);
|
||||
data_len = sizeof(struct XDATA);
|
||||
@ -1068,12 +1071,14 @@ static int handle_ncp_serv(void)
|
||||
uint8 ext_fhandle[2]; /* all zero */
|
||||
uint8 fhandle[4]; /* filehandle */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
uint32 fhandle = GET_BE32(input->fhandle);
|
||||
completition = (uint8)(-nw_close_datei(fhandle, 0));
|
||||
uint32 fhandle = GET_32(input->fhandle);
|
||||
completition = (uint8)(-nw_close_file(fhandle, 0));
|
||||
#if TEST_FNAME
|
||||
if (!completition && fhandle == test_handle) {
|
||||
do_druck++;
|
||||
test_handle = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1104,7 +1109,7 @@ static int handle_ncp_serv(void)
|
||||
(int)(ncprequest->task));
|
||||
if (fhandle > -1){
|
||||
data_len = sizeof(struct XDATA);
|
||||
U32_TO_BE32(fhandle, xdata->fhandle);
|
||||
U32_TO_32 (fhandle, xdata->fhandle);
|
||||
U16_TO_BE16(0, xdata->extfhandle);
|
||||
U16_TO_BE16(0, xdata->reserved);
|
||||
|
||||
@ -1187,7 +1192,7 @@ static int handle_ncp_serv(void)
|
||||
struct XDATA {
|
||||
uint8 size[4]; /* Position ??? */
|
||||
} *xdata=(struct XDATA*)responsedata;
|
||||
int fhandle = GET_BE32(input->fhandle);
|
||||
int fhandle = GET_32(input->fhandle);
|
||||
int size = nw_seek_datei(fhandle, 0);
|
||||
if (size > -1) {
|
||||
data_len = sizeof(struct XDATA);
|
||||
@ -1211,7 +1216,7 @@ static int handle_ncp_serv(void)
|
||||
uint8 size[2]; /* read bytes */
|
||||
uint8 data[2]; /* read data */
|
||||
} *xdata=(struct XDATA*)responsedata;
|
||||
int fhandle = GET_BE32(input->fhandle);
|
||||
int fhandle = GET_32 (input->fhandle);
|
||||
int max_size = GET_BE16(input->max_size);
|
||||
off_t offset = GET_BE32(input->offset);
|
||||
int zusatz = (offset & 1) ? 1 : 0;
|
||||
@ -1243,7 +1248,7 @@ static int handle_ncp_serv(void)
|
||||
uint8 data[2]; /* Schreibdaten */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
off_t offset = GET_BE32(input->offset);
|
||||
int fhandle = GET_BE32(input->fhandle);
|
||||
int fhandle = GET_32 (input->fhandle);
|
||||
int input_size = GET_BE16(input->size);
|
||||
int size = nw_write_datei(fhandle,
|
||||
input->data,
|
||||
@ -1268,8 +1273,8 @@ static int handle_ncp_serv(void)
|
||||
uint8 zoffset[4]; /* DestFile Offset */
|
||||
uint8 size[4]; /* copysize */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
int qfhandle = GET_BE32(input->qfhandle);
|
||||
int zfhandle = GET_BE32(input->zfhandle);
|
||||
int qfhandle = GET_32 (input->qfhandle);
|
||||
int zfhandle = GET_32 (input->zfhandle);
|
||||
off_t qoffset = GET_BE32(input->qoffset);
|
||||
off_t zoffset = GET_BE32(input->zoffset);
|
||||
uint32 input_size = GET_BE32(input->size);
|
||||
@ -1297,7 +1302,7 @@ static int handle_ncp_serv(void)
|
||||
uint8 zeit[2]; /* time */
|
||||
uint8 datum[2]; /* date */
|
||||
} *input = (struct INPUT *)ncprequest;
|
||||
int result = nw_set_fdate_time(GET_BE32(input->fhandle),
|
||||
int result = nw_set_fdate_time(GET_32(input->fhandle),
|
||||
input->datum, input->zeit);
|
||||
if (result <0) completition = (uint8) -result;
|
||||
}
|
||||
@ -1332,7 +1337,7 @@ static int handle_ncp_serv(void)
|
||||
(int)(ncprequest->task));
|
||||
|
||||
if (fhandle > -1){
|
||||
U32_TO_BE32(fhandle, xdata->fhandle);
|
||||
U32_TO_32 (fhandle, xdata->fhandle);
|
||||
U16_TO_BE16(0, xdata->ext_fhandle);
|
||||
U16_TO_BE16(0, xdata->reserve2);
|
||||
|
||||
@ -1708,7 +1713,7 @@ int main(int argc, char **argv)
|
||||
# if 1
|
||||
# ifdef SIOCIPXNCPCONN
|
||||
{
|
||||
int conn = atoi(*(argv+3));
|
||||
int conn = act_connection;
|
||||
int result = ioctl(0, SIOCIPXNCPCONN, &conn);
|
||||
XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result));
|
||||
}
|
||||
@ -1789,6 +1794,14 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
} /* while */
|
||||
|
||||
seteuid(0);
|
||||
# ifdef SIOCIPXNCPCONN
|
||||
{
|
||||
int conn = -act_connection;
|
||||
(void)ioctl(0, SIOCIPXNCPCONN, &conn);
|
||||
}
|
||||
# endif
|
||||
close_all();
|
||||
XDPRINTF((2,0, "leave nwconn pid=%d", getpid()));
|
||||
return(0);
|
||||
|
81
nwdbm.c
81
nwdbm.c
@ -1,4 +1,4 @@
|
||||
/* nwdbm.c 20-Jan-97 data base for mars_nwe */
|
||||
/* nwdbm.c 17-Apr-97 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
|
||||
@ -1119,6 +1119,14 @@ uint32 nw_new_obj_prop(uint32 wanted_id,
|
||||
return(obj.id);
|
||||
}
|
||||
|
||||
/* some property names */
|
||||
/*STANDARD NOVELL properties */
|
||||
static uint8 *pn_password=(uint8*) "PASSWORD";
|
||||
|
||||
/* OWN properties */
|
||||
static uint8 *pn_unix_user=(uint8*) "UNIX_USER";
|
||||
static uint8 *pn_special_flags=(uint8*)"SP_SU_FLAGS"; /* flag */
|
||||
|
||||
typedef struct {
|
||||
int pw_uid;
|
||||
int pw_gid;
|
||||
@ -1132,7 +1140,7 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id)
|
||||
{
|
||||
static MYPASSWD pwstat;
|
||||
char buff[200];
|
||||
if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){
|
||||
if (nw_get_prop_val_str(obj_id, pn_unix_user, buff) > 0){
|
||||
struct passwd *pw = getpwnam(buff);
|
||||
if (NULL != pw) {
|
||||
if (obj_id != 1 && !pw->pw_uid)
|
||||
@ -1205,7 +1213,7 @@ static int crypt_pw_ok(uint8 *password, char *passwd)
|
||||
static int loc_nw_test_passwd(uint8 *keybuff, uint8 *stored_passwd,
|
||||
uint32 obj_id, uint8 *vgl_key, uint8 *akt_key)
|
||||
{
|
||||
if (nw_get_prop_val_str(obj_id, "PASSWORD", stored_passwd) > 0) {
|
||||
if (nw_get_prop_val_str(obj_id, pn_password, stored_passwd) > 0) {
|
||||
nw_encrypt(vgl_key, stored_passwd, keybuff);
|
||||
return (memcmp(akt_key, keybuff, 8) ? -0xff : 0);
|
||||
} else { /* now we build an empty password */
|
||||
@ -1247,7 +1255,7 @@ int nw_test_unenpasswd(uint32 obj_id, uint8 *password)
|
||||
uint8 stored_passwd[200];
|
||||
MYPASSWD *pw;
|
||||
if (password && *password
|
||||
&& nw_get_prop_val_str(obj_id, "PASSWORD", stored_passwd) > 0 ) {
|
||||
&& nw_get_prop_val_str(obj_id, pn_password, stored_passwd) > 0 ) {
|
||||
uint8 s_uid[4];
|
||||
U32_TO_BE32(obj_id, s_uid);
|
||||
xstrcpy(passwordu, password);
|
||||
@ -1267,9 +1275,12 @@ int nw_test_unenpasswd(uint32 obj_id, uint8 *password)
|
||||
} else return(-0xff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int nw_set_enpasswd(uint32 obj_id, uint8 *passwd, int dont_ch)
|
||||
{
|
||||
uint8 *prop_name=(uint8*)"PASSWORD";
|
||||
uint8 *prop_name=pn_password;
|
||||
if (passwd && *passwd) {
|
||||
if ((!dont_ch) || (nw_get_prop_val_str(obj_id, prop_name, NULL) < 1))
|
||||
nw_new_obj_prop(obj_id, NULL, 0, 0, 0,
|
||||
@ -1496,13 +1507,41 @@ static void add_user_2_unx(uint32 u_id, char *unname)
|
||||
{
|
||||
if (unname && *unname)
|
||||
nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 ,
|
||||
"UNIX_USER", P_FL_ITEM, 0x33,
|
||||
pn_unix_user, P_FL_ITEM, 0x33,
|
||||
(char*)unname, strlen(unname), 1);
|
||||
}
|
||||
|
||||
extern int test_allow_password_change(uint32 id)
|
||||
{
|
||||
uint8 more_segments;
|
||||
uint8 property_flags;
|
||||
uint8 buff[200];
|
||||
int segment = 1;
|
||||
int result = nw_get_prop_val_by_obj_id(id, segment,
|
||||
pn_special_flags, strlen(pn_special_flags),
|
||||
buff, &more_segments, &property_flags);
|
||||
if (result > -1 && (GET_BE32(buff) & 1))
|
||||
return(-0xff);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void add_remove_special_flags(uint32 obj_id, int flags)
|
||||
/* add special flags to User, 0x1 = fixed-password */
|
||||
{
|
||||
if (flags) {
|
||||
uint8 buff[4];
|
||||
U32_TO_BE32(flags, buff);
|
||||
nw_new_obj_prop(obj_id, NULL, 0, 0, 0,
|
||||
pn_special_flags, P_FL_STAT|P_FL_ITEM, 0x33,
|
||||
buff, sizeof(buff), 1);
|
||||
} else
|
||||
(void)loc_delete_property(obj_id, pn_special_flags, 0, 1);
|
||||
}
|
||||
|
||||
static void add_user_g(uint32 u_id, uint32 g_id,
|
||||
char *name, char *unname,
|
||||
char *password, int dont_ch)
|
||||
char *password, int dont_ch,
|
||||
int flags, int set_flags)
|
||||
{
|
||||
/* Typ Flags Security */
|
||||
dont_ch = (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x31)
|
||||
@ -1519,6 +1558,8 @@ static void add_user_g(uint32 u_id, uint32 g_id,
|
||||
if (*password == '-') *password='\0';
|
||||
nw_set_passwd(u_id, password, dont_ch);
|
||||
}
|
||||
if (set_flags)
|
||||
add_remove_special_flags(u_id, flags);
|
||||
}
|
||||
|
||||
static void add_group(char *name, char *unname, char *password)
|
||||
@ -1715,16 +1756,32 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
char nname[100];
|
||||
char uname[100];
|
||||
char password[100];
|
||||
int anz=sscanf((char*)buff, "%s %s %s", nname, uname, password);
|
||||
char flagsstr[100];
|
||||
int flags=0;
|
||||
int set_flags=0;
|
||||
int anz=sscanf((char*)buff, "%s %s %s %s", nname, uname, password, flagsstr);
|
||||
if (anz > 1) {
|
||||
upstr(nname);
|
||||
if (anz > 2) upstr(password);
|
||||
else password[0] = '\0';
|
||||
if (anz > 2) {
|
||||
upstr(password);
|
||||
if (anz > 3) {
|
||||
flags=hextoi(flagsstr);
|
||||
set_flags++;
|
||||
} else if ( what == 13
|
||||
&& password[0] == '0'
|
||||
&& password[1] == 'X'
|
||||
&& password[2] >= '0'
|
||||
&& password[2] <= '9' ) {
|
||||
flags=hextoi(password);
|
||||
password[0] = '\0';
|
||||
set_flags++;
|
||||
}
|
||||
} else password[0] = '\0';
|
||||
if (what == 14)
|
||||
add_group(nname, uname, password);
|
||||
else
|
||||
add_user_g((12 == what) ? su_id : 0L, ge_id, nname,
|
||||
uname, password, 0);
|
||||
uname, password, 0, flags, set_flags);
|
||||
}
|
||||
} else if (15 == what) {
|
||||
char buf[100];
|
||||
@ -1785,7 +1842,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
xstrcpy(nname, pw->pw_name);
|
||||
upstr(nname);
|
||||
add_user_g(0L, ge_id, nname, pw->pw_name, auto_ins_passwd,
|
||||
(auto_ins_user == 99) ? 0 : 99);
|
||||
(auto_ins_user == 99) ? 0 : 99, 0, 0);
|
||||
} else {
|
||||
XDPRINTF((1,0, "Unix User:'%s' not added because passwd='%s'",
|
||||
pw->pw_name, pw->pw_passwd));
|
||||
|
3
nwdbm.h
3
nwdbm.h
@ -1,4 +1,4 @@
|
||||
/* nwdbm.h 20-Jan-97 */
|
||||
/* nwdbm.h 17-Apr-97 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -198,6 +198,7 @@ extern int nw_get_q_dirname(uint32 q_id, uint8 *buff);
|
||||
extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff);
|
||||
|
||||
extern void test_ins_unx_user(uint32 id);
|
||||
extern int test_allow_password_change(uint32 id);
|
||||
|
||||
extern int nw_fill_standard(char *servername, ipxAddr_t *adr);
|
||||
extern int nw_init_dbm(char *servername, ipxAddr_t *adr);
|
||||
|
56
nwfile.c
56
nwfile.c
@ -421,7 +421,9 @@ file_creat_open_ret:
|
||||
MDEBUG(D_FH_OPEN, {
|
||||
char fname[200];
|
||||
if (!fd_2_fname(fhandle, fname, sizeof(fname))){
|
||||
dprintf("Open/creat fd=%d, fn=`%s`", fhandle, fname);
|
||||
FILE_HANDLE *fh=fd_2_fh(fhandle);
|
||||
dprintf("Open/creat fd=%d, fn=`%s`, openmode=%s",
|
||||
fhandle, fname, (fh && (fh->fh_flags &FH_OPENED_RO)) ? "RO" : "RW" );
|
||||
}
|
||||
})
|
||||
return(fhandle);
|
||||
@ -441,15 +443,15 @@ int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit)
|
||||
return(-0x88); /* wrong filehandle */
|
||||
}
|
||||
|
||||
int nw_close_datei(int fhandle, int reset_reuse)
|
||||
int nw_close_file(int fhandle, int reset_reuse)
|
||||
{
|
||||
XDPRINTF((5, 0, "nw_close_datei handle=%d, anz_fhandles",
|
||||
XDPRINTF((5, 0, "nw_close_file handle=%d, anz_fhandles",
|
||||
fhandle, anz_fhandles));
|
||||
|
||||
MDEBUG(D_FH_OPEN, {
|
||||
char fname[200];
|
||||
int r=fd_2_fname(fhandle, fname, sizeof(fname));
|
||||
dprintf("nw_close_datei: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
|
||||
dprintf("nw_close_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
|
||||
})
|
||||
|
||||
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
|
||||
@ -495,6 +497,44 @@ int nw_close_datei(int fhandle, int reset_reuse)
|
||||
return(-0x88); /* wrong filehandle */
|
||||
}
|
||||
|
||||
|
||||
int nw_commit_file(int fhandle)
|
||||
{
|
||||
MDEBUG(D_FH_FLUSH, {
|
||||
char fname[200];
|
||||
int r=fd_2_fname(fhandle, fname, sizeof(fname));
|
||||
dprintf("nw_commit_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
|
||||
})
|
||||
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
|
||||
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
|
||||
if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) {
|
||||
if (!(fh->fh_flags & FH_IS_READONLY)) {
|
||||
int result=0;
|
||||
if (!(fh->fh_flags & FH_IS_PIPE) && fh->fd > -1) {
|
||||
int fd=dup(fh->fd);
|
||||
if (fd > -1) {
|
||||
if (!close(fh->fd)) {
|
||||
if (fh->tmodi > 0L) {
|
||||
struct utimbuf ut;
|
||||
ut.actime = ut.modtime = fh->tmodi;
|
||||
utime(fh->fname, &ut);
|
||||
fh->tmodi = 0L;
|
||||
}
|
||||
fh->fd=dup2(fd, fh->fd);
|
||||
} else
|
||||
result=-0x8c;
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
} else
|
||||
return(-0x8c);
|
||||
}
|
||||
}
|
||||
return(-0x88); /* wrong filehandle */
|
||||
}
|
||||
|
||||
|
||||
uint8 *file_get_unix_name(int fhandle)
|
||||
{
|
||||
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
|
||||
@ -735,4 +775,12 @@ int fd_2_fname(int fhandle, char *buf, int bufsize)
|
||||
return(-0x88);
|
||||
}
|
||||
|
||||
FILE_HANDLE *fd_2_fh(int fhandle)
|
||||
{
|
||||
if (fhandle > HOFFS && (--fhandle < anz_fhandles))
|
||||
return(&(file_handles[fhandle]));
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
4
nwfile.h
4
nwfile.h
@ -37,7 +37,8 @@ extern int file_creat_open(int volume, uint8 *unixname,
|
||||
extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit);
|
||||
|
||||
|
||||
extern int nw_close_datei(int fhandle, int reset_reuse);
|
||||
extern int nw_close_file(int fhandle, int reset_reuse);
|
||||
extern int nw_commit_file(int fhandle);
|
||||
|
||||
extern uint8 *file_get_unix_name(int fhandle);
|
||||
|
||||
@ -51,5 +52,6 @@ extern int nw_server_copy(int qfhandle, uint32 qoffset,
|
||||
extern int nw_lock_datei(int fhandle, int offset, int size, int do_lock);
|
||||
|
||||
extern int fd_2_fname(int fhandle, char *buf, int bufsize);
|
||||
extern FILE_HANDLE *fd_2_fh(int fhandle);
|
||||
|
||||
#endif
|
||||
|
@ -234,7 +234,7 @@ static void free_queue_job(int q_id)
|
||||
if (q_id > 0 && q_id <= anz_jobs) {
|
||||
INT_QUEUE_JOB **pp=&(queue_jobs[q_id-1]);
|
||||
uint32 fhandle = (*pp)->fhandle;
|
||||
if (fhandle > 0) nw_close_datei(fhandle, 1);
|
||||
if (fhandle > 0) nw_close_file(fhandle, 1);
|
||||
if (q_id == anz_jobs) {
|
||||
xfree(*pp);
|
||||
--anz_jobs;
|
||||
@ -323,7 +323,7 @@ int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
|
||||
if (result > -1) {
|
||||
jo->fhandle = (uint32) result;
|
||||
U16_TO_BE16(0, jo->q.o.job_file_handle);
|
||||
U32_TO_BE32(jo->fhandle, jo->q.o.job_file_handle+2);
|
||||
U32_TO_32(jo->fhandle, jo->q.o.job_file_handle+2);
|
||||
result = 0;
|
||||
}
|
||||
jo->q.o.server_station = 0;
|
||||
@ -359,7 +359,7 @@ int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
|
||||
|
||||
if (result > -1) {
|
||||
jo->fhandle = (uint32) result;
|
||||
U32_TO_BE32(jo->fhandle, jo->q.n.job_file_handle);
|
||||
U32_TO_32(jo->fhandle, jo->q.n.job_file_handle);
|
||||
result = 0;
|
||||
}
|
||||
U32_TO_BE32(0, jo->q.n.server_station);
|
||||
@ -401,7 +401,7 @@ int nw_close_file_queue(uint8 *queue_id,
|
||||
qpa.banner_user_name, qpa.banner_file_name);
|
||||
} else
|
||||
strmaxcpy((uint8*)printcommand, prc, prc_len);
|
||||
nw_close_datei(fhandle, 1);
|
||||
nw_close_file(fhandle, 1);
|
||||
jo->fhandle = 0L;
|
||||
if (NULL == (f = fopen(unixname, "r"))) {
|
||||
/* OK now we try the open as root */
|
||||
|
72
nwroute.c
72
nwroute.c
@ -1,4 +1,4 @@
|
||||
/* nwroute.c 12-Nov-96 */
|
||||
/* nwroute.c 15-Apr-97 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -66,7 +66,7 @@ static void insert_delete_net(uint32 destnet,
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
if (nd->is_up) {
|
||||
if (nd->net == destnet) {
|
||||
if (!do_delete) return; /* don't route device */
|
||||
if (!do_delete) return; /* don't alter device */
|
||||
nd_dev = nd;
|
||||
}
|
||||
if (nd->net == rnet) ndticks=nd->ticks;
|
||||
@ -95,23 +95,27 @@ static void insert_delete_net(uint32 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,0,"ROUTE DEL NET=0x%x over Router NET 0x%x",
|
||||
nr->net, rnet));
|
||||
ipx_route_del(nr->net);
|
||||
|
||||
if (nd_dev != NULL) { /* this is net to our device */
|
||||
/* I must delete and setup new, because there is */
|
||||
/* no direct way to delete this route from interface :( */
|
||||
exit_dev(nd_dev->devname, nd_dev->frame);
|
||||
init_dev(nd_dev->devname, nd_dev->frame, nd_dev->net);
|
||||
init_dev(nd_dev->devname, nd_dev->frame, nd_dev->net, 0);
|
||||
}
|
||||
|
||||
nr->net = 0L;
|
||||
} else {
|
||||
XDPRINTF((3,0,"ROUTE NOT deleted NET=0x%x, RNET=0x%x",
|
||||
nr->net, rnet));
|
||||
}
|
||||
|
||||
return;
|
||||
} else nr=nw_routes[k];
|
||||
|
||||
@ -392,7 +396,7 @@ void handle_rip(int fd, int ipx_pack_typ,
|
||||
ipxAddr_t *from_addr)
|
||||
|
||||
/* All received rip packets reach this function */
|
||||
/* It can be a RIP Request or a RIP Respons */
|
||||
/* It can be a RIP Request or a RIP Response */
|
||||
{
|
||||
int operation = GET_BE16(ipxdata->rip.operation);
|
||||
int entries = (data_len-2) / 8;
|
||||
@ -641,14 +645,22 @@ void send_sap_rip_broadcast(int mode)
|
||||
/* mode=0, standard broadcast */
|
||||
/* mode=1, first trie */
|
||||
/* mode=2, shutdown */
|
||||
/* mode=3, update routes */
|
||||
{
|
||||
static int flipflop=1;
|
||||
int force_print_routes=(mode == 1);
|
||||
if (auto_creat_interfaces)
|
||||
force_print_routes = look_for_interfaces();
|
||||
if (auto_detect_interfaces)
|
||||
force_print_routes += look_for_interfaces();
|
||||
if (mode) {
|
||||
if (mode == 3) {
|
||||
if (force_print_routes) {
|
||||
send_rip_broadcast(1);
|
||||
send_sap_broadcast(1);
|
||||
}
|
||||
} else {
|
||||
send_rip_broadcast(mode);
|
||||
send_sap_broadcast(mode);
|
||||
}
|
||||
} else {
|
||||
if (flipflop) {
|
||||
send_rip_broadcast(mode);
|
||||
@ -757,9 +769,27 @@ int test_ins_device_net(uint32 rnet)
|
||||
|
||||
if ( foundfree < 0 ) {
|
||||
if (anz_net_devices < MAX_NET_DEVICES) {
|
||||
NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]);
|
||||
nd=*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE));
|
||||
nd->ticks = 1;
|
||||
NW_NET_DEVICE **pnd;
|
||||
int matched=0;
|
||||
k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
nd = net_devices[k];
|
||||
if (nd->wildmask&3) {
|
||||
int dfound = !strcmp(nd->devname, rnetdevname);
|
||||
int ffound = nd->frame == rnetframe;
|
||||
if ( (dfound && ffound) || (dfound && (nd->wildmask&2) )
|
||||
|| (ffound && (nd->wildmask&1))) {
|
||||
pnd=&(net_devices[anz_net_devices++]);
|
||||
*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE));
|
||||
(*pnd)->wildmask = nd->wildmask;
|
||||
(*pnd)->ticks = nd->ticks;
|
||||
matched++;
|
||||
nd=*pnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched) return(0);
|
||||
} else {
|
||||
XDPRINTF((1, 0, "too many devices > %d, increase MAX_NET_DEVICES in config.h", anz_net_devices));
|
||||
return(0);
|
||||
@ -780,10 +810,11 @@ int test_ins_device_net(uint32 rnet)
|
||||
if (nr->net == rnet) {
|
||||
ipx_route_del(nr->net);
|
||||
nr->net = 0L;
|
||||
|
||||
/* I must delete and setup new, because there is */
|
||||
/* no direct way to delete this route from interface :( */
|
||||
exit_dev(nd->devname, nd->frame);
|
||||
init_dev(nd->devname, nd->frame, nd->net);
|
||||
init_dev(nd->devname, nd->frame, nd->net, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -810,7 +841,7 @@ static int look_for_interfaces(void)
|
||||
int flags;
|
||||
int fframe = read_interface_data((uint8*) buff, &rnet, NULL, &flags, dname);
|
||||
if (fframe < 0) continue;
|
||||
if (rnet > 0L && !(flags & 2)) {
|
||||
if (rnet > 0L && !(flags & 2)) { /* not internal */
|
||||
int found=0;
|
||||
k=-1;
|
||||
while (++k < anz_net_devices) {
|
||||
@ -822,7 +853,7 @@ static int look_for_interfaces(void)
|
||||
}
|
||||
if (found && nd->is_up) {
|
||||
if (nd->is_up == -2) nd->is_up=2; /* reset */
|
||||
} else find_diffs=test_ins_device_net(rnet);
|
||||
} else find_diffs+=test_ins_device_net(rnet);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
@ -830,7 +861,22 @@ static int look_for_interfaces(void)
|
||||
k = -1;
|
||||
while (++k < anz_net_devices) {
|
||||
nd=net_devices[k];
|
||||
if (nd->is_up < 0) nd->is_up = 0; /* this will be put DOWN */
|
||||
if (nd->is_up < 0) {
|
||||
int j;
|
||||
find_diffs++;
|
||||
nd->is_up = 0; /* this will be put DOWN */
|
||||
for (j=0; j < anz_routes; j++){
|
||||
NW_ROUTES *nr=nw_routes[j];
|
||||
if (nr && nr->rnet == nd->net)
|
||||
nr->net = 0L; /* remove route */
|
||||
}
|
||||
if (nd->wildmask & 1)
|
||||
new_str(nd->devname, "*");
|
||||
if (nd->wildmask & 2)
|
||||
nd->frame = -1;
|
||||
if (nd->wildmask & 4)
|
||||
nd->net = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(find_diffs);
|
||||
|
82
nwserv.c
82
nwserv.c
@ -1,4 +1,4 @@
|
||||
/* nwserv.c 12-Nov-96 */
|
||||
/* nwserv.c 12-Apr-97 */
|
||||
/* MAIN Prog for NWSERV + NWROUTED */
|
||||
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
uint32 internal_net = 0x0L; /* NETWORKNUMMER INTERN (SERVER) */
|
||||
int no_internal = 0; /* no use of internal net */
|
||||
int auto_creat_interfaces=0;
|
||||
int auto_detect_interfaces=0;
|
||||
|
||||
ipxAddr_t my_server_adr; /* Address of this server */
|
||||
char my_nwname[50]; /* Name of this server */
|
||||
@ -110,7 +110,7 @@ static int broadmillisecs = 2000; /* 2 sec */
|
||||
static time_t server_down_stamp = 0;
|
||||
static int server_goes_down_secs = 10;
|
||||
static int server_broadcast_secs = 60;
|
||||
static int save_ipx_routes = 0;
|
||||
static int ipx_flags = 0;
|
||||
|
||||
static int nearest_request_flag=0;
|
||||
|
||||
@ -749,7 +749,7 @@ static void handle_event(int fd, uint16 socknr, int slot)
|
||||
/* it also can be Packets from DOSEMU OR ncpfs on this machine */
|
||||
XDPRINTF((2,0,"Packet from OWN maschine:sock=0x%x", source_sock));
|
||||
}
|
||||
if (auto_creat_interfaces && test_ins_device_net(GET_BE32(source_adr.net)))
|
||||
if (auto_detect_interfaces && test_ins_device_net(GET_BE32(source_adr.net)))
|
||||
broadmillisecs = 3000; /* now faster rip/sap to new devices */
|
||||
#endif
|
||||
|
||||
@ -911,7 +911,7 @@ static void get_ini(int full)
|
||||
}
|
||||
break;
|
||||
|
||||
case 5 : save_ipx_routes=atoi(inhalt);
|
||||
case 5 : ipx_flags=hextoi(inhalt);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -976,8 +976,7 @@ static void get_ini(int full)
|
||||
errorp(11, "Get_ini", "No internal net, but more than 1 Device specified");
|
||||
exit(1);
|
||||
}
|
||||
init_ipx(internal_net, node, ipxdebug);
|
||||
|
||||
init_ipx(internal_net, node, ipxdebug, ipx_flags);
|
||||
for (k=0; k < anz_net_devices; k++){
|
||||
NW_NET_DEVICE *nd=net_devices[k];
|
||||
int result;
|
||||
@ -985,15 +984,21 @@ static void get_ini(int full)
|
||||
char *sp = "DEVICE=%s, FRAME=%s, NETWORK=0x%lx";
|
||||
(void) get_frame_name(frname, nd->frame);
|
||||
XDPRINTF((1, 0, sp, nd->devname, frname, nd->net));
|
||||
if ((result= init_dev(nd->devname, nd->frame, nd->net)) < 0) {
|
||||
|
||||
if (nd->devname[0] == '*') nd->wildmask|=1;
|
||||
if (nd->frame < 0) nd->wildmask|=2;
|
||||
if (!nd->net) nd->wildmask|=4;
|
||||
|
||||
if ((result=init_dev(nd->devname, nd->frame, nd->net, nd->wildmask)) < 0) {
|
||||
if (result == -99) {
|
||||
errorp(11, "init_dev", "AUTO device is only in combination with internal net allowed");
|
||||
exit(1);
|
||||
} else
|
||||
errorp(1, "init_dev", sp, nd->devname, frname, nd->net);
|
||||
} else if (!result)
|
||||
} else if (!result) {
|
||||
nd->is_up = 1;
|
||||
else auto_creat_interfaces=1;
|
||||
} else
|
||||
auto_detect_interfaces=1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
@ -1067,7 +1072,8 @@ static void close_all(void)
|
||||
|
||||
#ifdef LINUX
|
||||
# if INTERNAL_RIP_SAP
|
||||
if (!save_ipx_routes) {
|
||||
#if 0
|
||||
if (!(ipx_flags&1)) {
|
||||
for (j=0; j<anz_net_devices;j++) {
|
||||
NW_NET_DEVICE *nd=net_devices[j];
|
||||
if (nd->is_up) {
|
||||
@ -1077,7 +1083,8 @@ static void close_all(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
exit_ipx(!save_ipx_routes);
|
||||
#endif
|
||||
exit_ipx(ipx_flags);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
@ -1116,7 +1123,7 @@ static void sig_quit(int rsig)
|
||||
signal(rsig, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN); /* don't want it anymore */
|
||||
XDPRINTF((2, 0, "Got Signal=%d", rsig));
|
||||
fl_get_int=2;
|
||||
fl_get_int|=2;
|
||||
}
|
||||
|
||||
static void handle_hup_reqest(void)
|
||||
@ -1127,22 +1134,42 @@ static void handle_hup_reqest(void)
|
||||
write_to_ncpserv(0xeeee, 0, NULL, 0); /* inform ncpserv */
|
||||
write_to_nwbind( 0xeeee, 0, NULL, 0); /* inform nwbind */
|
||||
send_sap_rip_broadcast(1); /* firsttime broadcast */
|
||||
fl_get_int=0;
|
||||
}
|
||||
|
||||
static void sig_hup(int rsig)
|
||||
{
|
||||
fl_get_int=1;
|
||||
fl_get_int|=1;
|
||||
signal(SIGHUP, sig_hup);
|
||||
}
|
||||
|
||||
static void set_sigs(void)
|
||||
static void handle_usr1_request(void)
|
||||
{
|
||||
XDPRINTF((2,0, "Got USR1, update internal devices/routes"));
|
||||
send_sap_rip_broadcast(3);
|
||||
}
|
||||
|
||||
static void sig_usr1(int rsig)
|
||||
{
|
||||
fl_get_int|=4;
|
||||
signal(rsig, sig_usr1);
|
||||
}
|
||||
|
||||
static void set_sigs(int mode)
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
if (!mode) {
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
} else {
|
||||
signal(SIGTERM, sig_quit);
|
||||
signal(SIGQUIT, sig_quit);
|
||||
signal(SIGINT, sig_quit);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGHUP, sig_hup);
|
||||
signal(SIGUSR1, sig_usr1);
|
||||
}
|
||||
}
|
||||
|
||||
static int server_is_down=0;
|
||||
@ -1150,12 +1177,13 @@ static int server_is_down=0;
|
||||
static int usage(char *prog)
|
||||
{
|
||||
#if !IN_NWROUTED
|
||||
fprintf(stderr, "usage:\t%s [-v|-h|-k|y]\n", prog);
|
||||
fprintf(stderr, "usage:\t%s [-V|-h|-u|-k|y]\n", prog);
|
||||
#else
|
||||
fprintf(stderr, "usage:\t%s [-v|-h]|-k]\n", prog);
|
||||
fprintf(stderr, "usage:\t%s [-v|-h|-u|-k]\n", prog);
|
||||
#endif
|
||||
fprintf(stderr, "\t-v: print version\n");
|
||||
fprintf(stderr, "\t-V: print version\n");
|
||||
fprintf(stderr, "\t-h: send HUP to main process\n");
|
||||
fprintf(stderr, "\t-u: update int. routing table\n");
|
||||
fprintf(stderr, "\t-k: stop main process\n");
|
||||
#if !IN_NWROUTED
|
||||
fprintf(stderr, "\t y: start testclient code.\n");
|
||||
@ -1179,7 +1207,9 @@ int main(int argc, char **argv)
|
||||
switch (*a) {
|
||||
case 'h' : init_mode = 1; break;
|
||||
case 'k' : init_mode = 2; break;
|
||||
case 'v' : fprintf(stderr, "\n%s:Version %d.%d.pl%d\n",
|
||||
case 'u' : init_mode = 3; break;
|
||||
case 'v' :
|
||||
case 'V' : fprintf(stderr, "\n%s:Version %d.%d.pl%d\n",
|
||||
argv[0], _VERS_H_, _VERS_L_, _VERS_P_ );
|
||||
return(0);
|
||||
default : return(usage(argv[0]));
|
||||
@ -1199,6 +1229,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
setgroups(0, NULL);
|
||||
init_tools(IN_PROG, init_mode);
|
||||
set_sigs(0);
|
||||
get_ini(1);
|
||||
j=-1;
|
||||
while (++j < NEEDED_POLLS) {
|
||||
@ -1239,7 +1270,7 @@ int main(int argc, char **argv)
|
||||
/* now do polling */
|
||||
time_t broadtime;
|
||||
time(&broadtime);
|
||||
set_sigs();
|
||||
set_sigs(1);
|
||||
polls[NEEDED_SOCKETS].fd = fd_nwbind_in;
|
||||
|
||||
U16_TO_BE16(SOCK_NCP, my_server_adr.sock);
|
||||
@ -1277,10 +1308,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
if (fl_get_int) {
|
||||
if (fl_get_int == 1)
|
||||
if (fl_get_int & 1)
|
||||
handle_hup_reqest();
|
||||
else if (fl_get_int == 2)
|
||||
else if (fl_get_int & 4)
|
||||
handle_usr1_request();
|
||||
if (fl_get_int & 2)
|
||||
down_server();
|
||||
fl_get_int=0;
|
||||
}
|
||||
if (anz_poll > 0) { /* i have to work */
|
||||
struct pollfd *p = &polls[0];
|
||||
|
5
nwserv.h
5
nwserv.h
@ -1,4 +1,4 @@
|
||||
/* nwserv.h 16-Jul-96 */
|
||||
/* nwserv.h 10-Apr-97 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -19,7 +19,7 @@
|
||||
#define _M_NWSERV_H_
|
||||
extern uint32 internal_net; /* NETWORKNUMMER INTERN (SERVER) */
|
||||
extern int no_internal; /* no use of internal net */
|
||||
extern int auto_creat_interfaces;
|
||||
extern int auto_detect_interfaces;
|
||||
extern ipxAddr_t my_server_adr; /* Address of this server */
|
||||
extern char my_nwname[50]; /* Name of this server */
|
||||
extern int print_route_tac; /* every x broadcasts print it */
|
||||
@ -33,6 +33,7 @@ typedef struct {
|
||||
int ticks; /* ether:ticks=1, isdn:ticks=7 */
|
||||
uint32 net; /* NETWORK NUMBER */
|
||||
int is_up; /* Is this device up ? */
|
||||
int wildmask; /* wildmask, 1=name, 2=frame, 4=net */
|
||||
} NW_NET_DEVICE;
|
||||
|
||||
/* <========== DEVICES ==========> */
|
||||
|
38
tools.c
38
tools.c
@ -1,4 +1,4 @@
|
||||
/* tools.c 30-Dec-96 */
|
||||
/* tools.c 10-Apr-97 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -324,6 +324,21 @@ static void creat_pidfile(void)
|
||||
}
|
||||
}
|
||||
|
||||
void get_debug_level(uint8 *buf)
|
||||
{
|
||||
char buf1[300], buf2[300];
|
||||
int i=sscanf((char*)buf, "%s %s", buf1, buf2);
|
||||
if (i > 0) {
|
||||
nw_debug=atoi((char*)buf1);
|
||||
if (i > 1) {
|
||||
char dummy;
|
||||
if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1)
|
||||
sscanf(buf2, "%lx", &debug_mask);
|
||||
} else
|
||||
debug_mask=0;
|
||||
}
|
||||
}
|
||||
|
||||
void init_tools(int module, int options)
|
||||
{
|
||||
uint8 buf[300];
|
||||
@ -354,6 +369,8 @@ void init_tools(int module, int options)
|
||||
sig = SIGHUP;
|
||||
} else if (options == 2) { /* kill prog */
|
||||
sig = SIGTERM;
|
||||
} else if (options == 3) { /* kill prog */
|
||||
sig = SIGUSR1;
|
||||
} else {
|
||||
errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" ,
|
||||
kill_pid, pidfn);
|
||||
@ -361,7 +378,7 @@ void init_tools(int module, int options)
|
||||
}
|
||||
if (kill_pid > 1) kill(kill_pid, sig);
|
||||
exit(0);
|
||||
} else if (options == 1 || options == 2) {
|
||||
} else if (options == 1 || options == 2 || options == 3) {
|
||||
errorp(11, "INIT", "Program not running yet" );
|
||||
exit(1);
|
||||
}
|
||||
@ -376,16 +393,7 @@ void init_tools(int module, int options)
|
||||
} else if (202 == what) {
|
||||
new_log = atoi((char*)buf);
|
||||
} else if (100+module == what) {
|
||||
char buf1[300], buf2[300];
|
||||
int i=sscanf((char*)buf, "%s %s", buf1, buf2);
|
||||
if (i > 0) {
|
||||
nw_debug=atoi((char*)buf1);
|
||||
if (i > 1) {
|
||||
char dummy;
|
||||
if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1)
|
||||
sscanf(buf2, "%lx", &debug_mask);
|
||||
}
|
||||
}
|
||||
get_debug_level(buf);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
@ -397,8 +405,10 @@ void init_tools(int module, int options)
|
||||
if (fd) exit((fd > 0) ? 0 : 1);
|
||||
my_pid=getpid();
|
||||
}
|
||||
if (NULL == (logfile = fopen(logfilename,
|
||||
(new_log && (NWSERV == module || NWROUTED == module)) ? "w" : "a"))) {
|
||||
if (new_log && (NWSERV == module || NWROUTED == module))
|
||||
unlink(logfilename);
|
||||
|
||||
if (NULL == (logfile = fopen(logfilename, "a"))) {
|
||||
logfile = stderr;
|
||||
errorp(1, "INIT", "Cannot open logfile='%s'",logfilename);
|
||||
exit(1);
|
||||
|
1
tools.h
1
tools.h
@ -50,6 +50,7 @@ extern char *get_div_pathes(char *buff, char *name, int what, char *p, ... );
|
||||
|
||||
extern int get_ini_int(int what);
|
||||
extern void get_ini_debug(int what);
|
||||
extern void get_debug_level(uint8 *buf);
|
||||
extern void init_tools(int module, int options);
|
||||
extern void exit_tools(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user