mars_nwe-0.99.pl01

This commit is contained in:
Mario Fetka 2011-11-13 00:38:59 +01:00
parent fbd3b13b23
commit 51b8e80774
33 changed files with 2833 additions and 931 deletions

View File

@ -15,5 +15,9 @@
#define D_FN_NAMES 8 #define D_FN_NAMES 8
#define D_FN_SEARCH 0x10 /* file search */ #define D_FN_SEARCH 0x10 /* file search */
/* NWBIND */
#define D_BIND_REQ 0x8000 /* all Requests */
#endif #endif

View File

@ -10,6 +10,7 @@ If you have problems.
Section 1: volumes Section 1: volumes
Section 3: Number of the internal network Section 3: Number of the internal network
Section 4: IPX-devices Section 4: IPX-devices
Section 5: device flags
Section 6: version-"spoofing" Section 6: version-"spoofing"
Section 12: supervisor-login Section 12: supervisor-login
If you do not have success, please make one try with If you do not have success, please make one try with
@ -23,8 +24,8 @@ If you have problems.
some short notes for problem- or bug-reports. some short notes for problem- or bug-reports.
--------------------------------------------- ---------------------------------------------
- report your running environment - report your running environment
full mars_nwe version, example: 0.98.pl5 full mars_nwe version, example: 0.99.pl0
linux-kernel, 2.0.23 linux-kernel, 2.0.29
exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. ) exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. )
changes you made into nwserv.conf(nw.ini), config.h. changes you made into nwserv.conf(nw.ini), config.h.
- if you send nwserv.conf, please remove the comments first. - if you send nwserv.conf, please remove the comments first.

View File

@ -1,6 +1,6 @@
Sorry, this is in German only. Sorry, this is in German only.
User important notes are in the NEWS file. User important notes are in the NEWS file.
Aenderungen in mars_nwe bis zum : 14-Jul-97 Aenderungen in mars_nwe bis zum : 08-Aug-97
-------------------------------- --------------------------------
Erste 'oeffentliche' Version Erste 'oeffentliche' Version
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -349,3 +349,14 @@ Erste 'oeffentliche' Version
- Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.) - Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.)
korrigiert. korrigiert.
<----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- namespace routine delete file/dir um wildcardhandling erweitert fuer
client32. (W95)
- einfache Semaphore Routinen eingebaut.
- Routine 0x16,0x2f eingebaut. (fuer Pete)
- Quota Support wieder zum Laufen gebracht.
Durch Bindery Security Fixes funktionierte Quota Support
nicht mehr.
- im MAIL Verzeichnis werden nun im Unterverzeichnis user symbolische Links
der Login Namen erzeugt.
<----- ^^^^^^^^^^ pl1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -6,6 +6,9 @@ Michael Beddow <m.beddow@servelan.co.uk>
Thomas Behr <Thomas.Behr@uvw.uni-bayreuth.de> Thomas Behr <Thomas.Behr@uvw.uni-bayreuth.de>
testings, wrote syslog stuff testings, wrote syslog stuff
Peter Beno <Peter.Beno@anasoft.ana.sk>
testings+bugfixes
Guntram Blohm <gbl%th7csun1@str.daimler-benz.com> Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
testing router code on token ring testing router code on token ring
wrote the 'crypted change password' routines ! wrote the 'crypted change password' routines !
@ -46,6 +49,9 @@ Volker Lendecke <lendecke@math.uni-goettingen.de>
Ambrose Li <acli@acli.interlog.com> Ambrose Li <acli@acli.interlog.com>
gave hints, patches, docs gave hints, patches, docs
Andreas Liebmann <Liebmann@bbs1.btf.st.schule.de>
docs
James B. MacLean <macleajb@ednet.ns.ca> James B. MacLean <macleajb@ednet.ns.ca>
many testings+notes many testings+notes

View File

@ -49,6 +49,10 @@ A: Give the volume the 'O' flag.
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR] [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR]
"SupportLFN"=hex:02 "SupportLFN"=hex:02
A: Pascal Haible reported that he had to set system.ini, too.
[nwredir]
SupportLFN=2
Q: I have 2 Eth-devices (one for IP/IPX and one for IPX only) Q: I have 2 Eth-devices (one for IP/IPX and one for IPX only)
and after starting mars_nwe I have strange problems with my IP-net. and after starting mars_nwe I have strange problems with my IP-net.
A: Make sure that all Eth-devices have an assigned IP address, even if A: Make sure that all Eth-devices have an assigned IP address, even if

View File

@ -4,7 +4,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
die IPX-Interfaces per ini/conf Datei konfigurieren die IPX-Interfaces per ini/conf Datei konfigurieren
und als RIP/SAP Router arbeiten. und als RIP/SAP Router arbeiten.
Dieses ist der default Modus. Es werden keine weiteren Dieses ist der default Modus. Es werden keine weiteren
Programme wie ipx-configure oder IPX rip/sap Daemons Programme wie ipx-interface, ipx-configure oder IPX rip/sap Daemons
benoetigt. benoetigt.
In diesem Modus wurde das korrekte Zusammenspiel mit In diesem Modus wurde das korrekte Zusammenspiel mit
dosemu, ncpfs oder Caldera's nwclient getestet. dosemu, ncpfs oder Caldera's nwclient getestet.
@ -21,7 +21,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
Netwerknummer erhalten. Netwerknummer erhalten.
Es muss ein Eintrag '4' mit Netzwerk Nummer = 0, Es muss ein Eintrag '4' mit Netzwerk Nummer = 0,
Device = '*' und Frame = 'auto' fuer ein 'autodetect' Interface Device = '*' und Frame = 'auto' fuer ein 'autodetect' Interface
vorhanden sein. vorhanden sein und Eintrag '5' muss flag 2 enthalten.
Beispiel fuer conf/ini Datei: (siehe auch: examples/nw.ini) Beispiel fuer conf/ini Datei: (siehe auch: examples/nw.ini)
3 0x0 # verwende IP Nummer als Internal Net. 3 0x0 # verwende IP Nummer als Internal Net.
4 0x0 * AUTO # autodetect interfaces. 4 0x0 * AUTO # autodetect interfaces.
@ -38,8 +38,8 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
2. Mars_nwe soll nur als File Server Verwendung finden, d.h. 2. Mars_nwe soll nur als File Server Verwendung finden, d.h.
Routing usw. soll von anderen Programmen erledigt werden. Routing usw. soll von anderen Programmen erledigt werden.
-> Die IPX-Interfaces muessen durch andere Programme/Tools -> Die IPX-Interfaces muessen durch andere Programme/Tools
wie 'ipx-configure' oder aehnliche eingerichtet werden wie 'ipx-interface, ipx-configure' oder aehnliche eingerichtet
und es muss ein rip/sap router/daemon eingerichtet sein. werden und es muss ein rip/sap router/daemon eingerichtet sein.
In mars_nwe/config.h muss folgende Zeile vorhanden sein. In mars_nwe/config.h muss folgende Zeile vorhanden sein.
#define INTERNAL_RIP_SAP 0 #define INTERNAL_RIP_SAP 0
@ -72,5 +72,46 @@ sind.
Falls nwserv nicht daemonisiert wurde, kann der Server mit ^C Falls nwserv nicht daemonisiert wurde, kann der Server mit ^C
wieder gestoppt werden, ansonsten muss nwserv per Dos Client wieder gestoppt werden, ansonsten muss nwserv per Dos Client
(fconsole server down) gestoppt werden (Supervisor) oder per (fconsole server down) gestoppt werden (Supervisor) oder per
'kill' Befehl. Je nach Eintrag 210 in der nw.ini Datei kann 'nwserv -k' Befehl. Je nach Eintrag 210 in der nw.ini Datei kann
das einige Sekunden dauern. das einige Sekunden dauern.
Erlaeuterungen zu Punkt 1 in /etc/nwserv.conf :
Wenn der NetAdmin die Homeverzeichnisse des LINUX-Servers dem einzelnen
Usern durch das MAP Kommando bereitstellt, kann er das auf
zwei verschiedene Arten zustandebringen:
Angenommen, der User test2 hat sich am NWE angemeldet. Er hat bereits Dateien
in seinem Verzeichnis /home/test2 gespeichert.
Je nachdem welcher Eintrag 1 in der Datei /etc/nwserv.conf (natuerlich
neben anderen) vorgenommen worden ist, hat das MAP-Kommando ein
anderes Ergebnis:
Variante 1 Variante2
Befehl DOS
MAP H:=MARS\HOMEDIR: MAP H:=MARS\HOMEDIR:
Eintrag in /etc/nwserv.conf
1 HOMEDIR ~ k 1 HOMEDIR /home k
Resultat DIR *.*
Der Inhalt des Verzeichnisses Es werden alle unter /home
/home/test2 erscheint unter auf dem LINUX-Server enthaltenen
Laufwerk H. Verzeichnisse angezeigt. Der
D.h. die bereits vom User User test2 muesste also noch ein
test2 gespeicherten zwei cd /test2 machen, um seine
Dateien. Dateien anschauen zu koennen.
Achtung !
Ein Eintrag in /etc/nwserv.conf
1 HOMEDIR /home/~ k
macht bestimmt nicht das was erwartet wird.
Nur ein "~" ohne vorlaufenden Pfad hat die besondere Bedeutung
des Homedirs, ein "/home/~" als Verzeichnis gilt als 'normales' Volume
das den 'normalen' Pfad "/home/~" exportiert.

View File

@ -1,3 +1,7 @@
------16-Aug-97--- 0.99.pl1 ---------
- print queue handling changed. (please look into examples/nw.ini)
- simple semaphore calls added.
- in mail directory subdirectory 'user' added with symlinks to mail/user-id's.
------31-Jul-97--- 0.99.pl0 --------- ------31-Jul-97--- 0.99.pl0 ---------
- Client-32 from Novell should now work. (added vol/dev/inode/path cache) - Client-32 from Novell should now work. (added vol/dev/inode/path cache)
The cache directory '/var/spool/nwserv/.volcache' should/can be controlled The cache directory '/var/spool/nwserv/.volcache' should/can be controlled

View File

@ -1,6 +1,6 @@
Begin3 Begin3
Title: mars_nwe Title: mars_nwe
Version: 0.99.pl0 Version: 0.99.pl1
Entered-date: 31-Jul-97 Entered-date: 31-Jul-97
Description: Full netware-emulator (src), beta. Description: Full netware-emulator (src), beta.
Supports file-services, bindery-services, Supports file-services, bindery-services,
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@stover.f.eunet.de (Martin Stover) Author: mstover@stover.f.eunet.de (Martin Stover)
Maintained-by: 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 Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
240kB mars_nwe-0.99.pl0.tgz 240kB mars_nwe-0.99.pl1.tgz
Alternate-site: sunsite.unc.edu:/pub/Linux/system/filesystems/ncpfs Alternate-site: sunsite.unc.edu:/pub/Linux/system/filesystems/ncpfs
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
Copying-policy: GNU Copying-policy: GNU

View File

@ -2,12 +2,14 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator # This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux. # for Linux.
# #
# last changed: 20-Jul-97 # last changed: 30-Aug-97
#
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !! # !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
# #
# since version 0.98.pl11: # since version 0.98.pl11:
# the most important options in config.h can now be altered in # the most important options in config.h can now be altered in
# this file begin at section 60. # this file begin at section 60.
#
# This file specifies which Linux-resources (printers, users, directories) # This file specifies which Linux-resources (printers, users, directories)
@ -68,6 +70,31 @@
# volume; use the special name "~" to refer to the users # volume; use the special name "~" to refer to the users
# individual home-directory # individual home-directory
# #
# Attention ! A directory entry like "/home/~"
# do not work. Only is simple "~" as directory name
# has this special meaning.
#
# If the netadmin wants to map the homedirectories with the MAP-Command to
# every user, he can do it in two variants:
# We suppose that the user test2 is logged in MARS_NWE. He has files
# earlier stored in his homedirectory /home/test2.
# In case of entry 1 in /etc/nwserv.conf (naturally amongst other entries)
# there are other results of the MAP-command.
#
# Variant 1 Variant 2
#
#DOS-Command MAP H:=MARS\HOMEDIR: MAP H:=MARS\HOMEDIR:
#
#Entry in /etc/nwserv.conf
# 1 HOMEDIR ~ k 1 HOMEDIR /home k
#
#Result of DIR *.* All files stored in All homedirs of the
# /home/test2 will shown. users will shown.
# Showing his own files
# it is a command like
# CD test2 and then
# dir *.* necessary.
#
# OPTIONS: none or some of the following characters (without a seperator) # OPTIONS: none or some of the following characters (without a seperator)
# #
# Next two options control DOS and OS/2 namespace. # Next two options control DOS and OS/2 namespace.
@ -193,7 +220,7 @@
# #
# Under Linux, it is possible to let the kernel creat all ipx-devices # 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) # 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 # if there are other IPX/NCP servers on the same net which are setup
# correctly. It can be switched on in section '5'. # correctly. It can be switched on in section '5'.
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Syntax: # Syntax:
@ -561,31 +588,50 @@
# #
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Syntax: # Syntax:
# 21 QUEUE_NAME QUEUE_DIR PRINT_COMMAND # 21 QUEUE_NAME [QUEUE_DIR] [PRINT_COMMAND]
# #
# QUEUE_NAME: the name of the print queue on client-side (to make it # QUEUE_NAME: the name of the print queue on client-side (to make it
# perfectly clear: _not_ the Linux-queue) # perfectly clear: _not_ the Linux-queue)
# QUEUE_DIR: spooling directory for the print-jobs. # QUEUE_DIR: spooling directory for the print-jobs.
# The name is the DOS (not Unix) name of this # The name is the DOS (not Unix) name of this
# directory. # directory.
# It should be placed on the first defined volume. # It must be placed on the first defined volume.
# (standard name is SYS volume). # (standard name is SYS volume).
# Then it will be created at starttime of mars_nwe. # Then it will be created at starttime of mars_nwe.
# It must exist before printing. # It must exist before printing.
# (_not_ the spooling-directories of the Linux-lpd) # (_not_ the spooling-directories of the Linux-lpd)
# NOTE !
# A '-' sign as QUEUE_DIR has special meaning of
# 'standard' queuedir name. ( SYS:\SYSTEM\queueid.QDR )
#
# PRINT_COMMAND: command used for serving the print-jobs under Linux # PRINT_COMMAND: command used for serving the print-jobs under Linux
# (see "man lpr" and "man magicfilter" for details) # (see "man lpr" and "man magicfilter" for details)
# if the '!' is last parameter of command then # if the '!' is last parameter of command then
# the queue-packet fields 'banner_user_name' # the queue-packet fields 'banner_user_name'
# and 'banner_file_name' will be added to the # and 'banner_file_name' will be added to the
# command as last parameters. # command as last parameters.
# NOTE !
# If a print command is not specified the job can/must be
# printed by any print server.
# (e.g. pserver (ncpfs utils) or external printserver)
# #
# Examples: # Examples:
# 21 LASER SYS:/PRINT/L lpr -Plaser # 21 LASER - lpr -Plaser
# 21 OCTOPUSS SYS:/PRINT/O lpr -Php_deskjet # 21 OCTOPUSS
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# =========================================================================
# Section 22: print server entries (optional)
# adds printserver entries into bindery
# e.g. to enable printing with ncpfs pserver
# -------------------------------------------------------------------------
# Syntax:
# 22 PSERVER_NAME QUEUE_NAME
# Examples:
# 22 PS1 OCTOPUSS
# ========================================================================= # =========================================================================
# Section 30: Burst mode values (optional) # Section 30: Burst mode values (optional)
# #
@ -605,10 +651,12 @@
40 /var/spool/nwserv/.volcache 40 /var/spool/nwserv/.volcache
# 41 = path for share/lock files # 41 = path for share/lock files
41 /var/spool/nwserv/.locks 41 /var/spool/nwserv/.locks
# 42 = path for spool dir
42 /var/spool/nwserv
#
# #
# 45 = path for bindery file's # 45 = path for bindery file's
45 /etc 45 /etc
# ========================================================================= # =========================================================================
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru> # Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
# Tables for DOS->Unix names translation & upper/lowercase translations # Tables for DOS->Unix names translation & upper/lowercase translations

166
extpipe.c Normal file
View File

@ -0,0 +1,166 @@
/* extpipe.c 08-Aug-97 */
/* (C)opyright (C) 1993,1996 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 "extpipe.h"
static char **build_argv(char *buf, int bufsize, char *command)
/* routine returns **argv for use with execv routines */
/* buf will contain the path component */
{
int len = strlen(command);
int offset = ((len+4) / 4) * 4; /* aligned offset for **argv */
int components = (bufsize - offset) / 4;
if (components > 1) { /* minimal argv[0] + NULL */
char **argv = (char **)(buf+offset);
char **pp = argv;
char *p = buf;
char c;
int i=0;
--components;
memcpy(buf, command, len);
memset(buf+len, 0, bufsize - len);
*pp = p;
while ((0 != (c = *p++)) && i < components) {
if (c == 32 || c == '\t') {
*(p-1) = '\0';
if (*p != 32 && *p != '\t') {
*(++pp)=p;
i++;
}
} else if (!i && c == '/') { /* here i must get argv[0] */
*pp=p;
}
}
XDPRINTF((5, 0, "build_argv, path='%s'", buf));
pp=argv;
while (*pp) {
XDPRINTF((5, 0, "build_argv, argv='%s'", *pp));
pp++;
}
return(argv);
}
return(NULL);
}
static void close_piped(int piped[3][2])
{
int j=3;
while (j--) {
int k=2;
while (k--) {
if (piped[j][k] > -1){
close(piped[j][k]);
piped[j][k] = -1;
}
}
}
}
static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp)
{
int piped[3][2];
int lpid=-1;
int j=3;
char buf[300];
char **argv=build_argv(buf, sizeof(buf), command);
if (argv == NULL) return(-1);
while (j--){
int k=2;
while(k--) piped[j][k] = -1;
}
if (! (pipe(&piped[0][0]) > -1 && pipe(&piped[1][0]) > -1
&& pipe(&piped[2][0]) > -1 && (lpid=fork()) > -1)) {
close_piped(piped);
return(-1);
}
if (lpid == 0) { /* Child */
signal(SIGTERM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
signal(SIGHUP, SIG_DFL);
j=3;
while(j--) close(j);
j=3;
while(j--) {
int x = (j) ? 0 : 1;
int x_ = (j) ? 1 : 0;
close(piped[j][x] );
dup2( piped[j][x_], j);
close(piped[j][x_] );
}
if (uid > -1 || gid > -1) {
seteuid(0);
if (gid > -1) setgid(gid);
if (uid > -1) setuid(uid);
if (gid > -1) setegid(gid);
if (uid > -1) seteuid(uid);
}
execvp(buf, argv);
exit(1); /* Never reached I hope */
}
j=-1;
while (++j < 3) {
int x = (j) ? 0 : 1;
int x_ = (j) ? 1 : 0;
close(piped[j][x_]);
piped [j][x_] = -1;
fp->fds[j] = piped[j][x];
}
return(lpid);
}
int ext_pclose(FILE_PIPE *fp)
{
int status=-1;
void (*intsave) (int) = signal(SIGINT, SIG_IGN);
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
int j = 3;
while (j--) close(fp->fds[j]);
if (fp->command_pid != waitpid(fp->command_pid, &status, 0)) {
kill(fp->command_pid, SIGTERM);
waitpid(fp->command_pid, &status, 0);
}
kill(fp->command_pid, SIGKILL);
signal(SIGINT, intsave);
signal(SIGQUIT, quitsave);
signal(SIGHUP, hupsave);
xfree(fp);
return(status);
}
FILE_PIPE *ext_popen(char *command, int uid, int gid)
{
FILE_PIPE *fp=(FILE_PIPE*) xcmalloc(sizeof(FILE_PIPE));
void (*intsave) (int) = signal(SIGINT, SIG_IGN);
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
if ((fp->command_pid = x_popen(command, uid, gid, fp)) < 0) {
xfree(fp);
fp=NULL;
XDPRINTF((1, 0x10, "ext_popen failed:uid=%d, gid=%d,command='%s'",
uid, gid, command));
}
signal(SIGINT, intsave);
signal(SIGQUIT, quitsave);
signal(SIGHUP, hupsave);
return(fp);
}

16
extpipe.h Normal file
View File

@ -0,0 +1,16 @@
/* extpipe.h 08-Aug-97 */
#ifndef _EXTPIPE_H_
#define _EXTPIPE_H_
/* enhanced pipe handling */
typedef struct {
int fds[3]; /* filedescriptor to 0,1,2 of new process */
int command_pid; /* pid of piped command */
int flags; /* special flags */
} FILE_PIPE;
extern int ext_pclose(FILE_PIPE *fp);
extern FILE_PIPE *ext_popen(char *command, int uid, int gid);
#endif

View File

@ -1,5 +1,5 @@
#if 0 #if 0
#makefile.unx 09-Jul-97 #makefile.unx 09-Aug-97
#endif #endif
VPATH=$(V_VPATH) VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0 V_H=0
V_L=99 V_L=99
P_L=0 P_L=1
#define D_P_L 1 #define D_P_L 1
DISTRIB=mars_nwe DISTRIB=mars_nwe
@ -113,24 +113,26 @@ PROGS=$(INSTALLPROGS) $(PROG8)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
nwqueue$(O) nameos2$(O) nwfname$(O) nwshare$(O) nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O)
OBJ4= $(OBJ1) OBJ4= $(OBJ1)
OBJ5= $(OBJ1) OBJ5= $(OBJ1)
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O)
OBJ7= $(OBJ1) $(EMUTLIOBJ1) OBJ7= $(OBJ1) $(EMUTLIOBJ1)
OBJ8= $(OBJ6) OBJ8= $(OBJ6)
OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
$(EMUTLIOBJ1) $(NWROUTE_O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\
nwqueue$(O) nameos2$(O) \ nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) \ nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \
$(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \
$(PROG7)$(O) $(PROG8)$(O) $(PROG7)$(O) $(PROG8)$(O)
HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \
unxfile$(O) unxfile$(O)
HOBJ6= $(PROG6)$(O) sema$(O)
#if 0 #if 0
#$(PROG1): $(PROG1)$(O) $(OBJ1) #$(PROG1): $(PROG1)$(O) $(OBJ1)
# $(CC) -o $(VPATH)/$(PROG1) $(PROG1)$(O) $(OBJ1) $(CRYPTLIB) $(NSLLIB) # $(CC) -o $(VPATH)/$(PROG1) $(PROG1)$(O) $(OBJ1) $(CRYPTLIB) $(NSLLIB)
@ -162,6 +164,7 @@ $(PROG8): $(PROG8)$(O) $(OBJ8)
$(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) $(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB)
$(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h
$(HOBJ6): nwbind.h sema.h
$(OBJS): net.h config.h $(OBJS): net.h config.h
$(PROG7)$(O): nwserv.c nwroute.c $(PROG7)$(O): nwserv.c nwroute.c
tools$(O): $(DESTMAKEFILE) tools$(O): $(DESTMAKEFILE)

View File

@ -249,7 +249,7 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
continue; continue;
default : if (soptions & VOL_OPTION_IGNCASE) { default : if (soptions & VOL_OPTION_IGNCASE) {
if (!dfn_imatch(*s, *p)) if (!dfn_imatch(*s, pc))
return(0); return(0);
} else if (pc != *s) return(0); } else if (pc != *s) return(0);
++s; ++s;

View File

@ -1,4 +1,4 @@
/* namspace.c 30-Jul-97 : NameSpace Services, mars_nwe */ /* namspace.c 12-Aug-97 : NameSpace Services, mars_nwe */
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */
/* Its still dirty, but it should work fairly well */ /* Its still dirty, but it should work fairly well */
@ -967,15 +967,24 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe,
memset(p, 0, result+2); memset(p, 0, result+2);
if ( (!S_ISDIR(stb->st_mode))
&& (voloptions & VOL_OPTION_IS_PIPE) ) {
(void)time(&(stb->st_mtime));
stb->st_size = 0x70000000|(stb->st_mtime&0xfffffff);
stb->st_atime = stb->st_mtime;
}
if (infomask & INFO_MSK_DATA_STREAM_SPACE) { if (infomask & INFO_MSK_DATA_STREAM_SPACE) {
U32_TO_32(stb->st_size, p); U32_TO_32(stb->st_size, p);
} }
p += 4; p += 4;
if (infomask & INFO_MSK_ATTRIBUTE_INFO) { if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
uint32 attrib = (voloptions & VOL_OPTION_IS_PIPE) uint32 attrib = ( (!S_ISDIR(stb->st_mode))
? (uint32) FILE_ATTR_SHARE && (voloptions & VOL_OPTION_IS_PIPE) )
: (uint32) un_nw_attrib(stb, 0, 0); ? (uint32) FILE_ATTR_SHARE|FILE_ATTR_A
: (uint32) un_nw_attrib(stb, 0, 0);
U32_TO_32(attrib, p); U32_TO_32(attrib, p);
p += 4; p += 4;
U16_TO_16((uint16)(attrib & 0xFFFF), p); U16_TO_16((uint16)(attrib & 0xFFFF), p);
@ -1517,7 +1526,8 @@ static int nw_open_creat_file_or_dir(
int exist = result; int exist = result;
uint8 last_part[258]; uint8 last_part[258];
*last_part='\0'; *last_part='\0';
if (result < 0 && (opencreatmode & OPC_MODE_CREAT)) { /* do not exist */ if (result < 0 && (opencreatmode & (OPC_MODE_CREAT|OPC_MODE_REPLACE))) {
/* do not exist */
result = build_base(namespace, nwp, pathes, 1, last_part); result = build_base(namespace, nwp, pathes, 1, last_part);
XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'", XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'",
result, last_part)); result, last_part));
@ -1533,7 +1543,7 @@ static int nw_open_creat_file_or_dir(
if (!(creatattrib & FILE_ATTR_DIR)) { if (!(creatattrib & FILE_ATTR_DIR)) {
int creatmode=0; /* open */ int creatmode=0; /* open */
int attrib=0; int attrib=0;
if (opencreatmode & (OPC_MODE_OPEN | OPC_MODE_CREAT) ) { if (opencreatmode & (OPC_MODE_OPEN | OPC_MODE_CREAT| OPC_MODE_REPLACE) ) {
if (opencreatmode & OPC_MODE_CREAT) { if (opencreatmode & OPC_MODE_CREAT) {
#if 0 #if 0
if (exist > -1 && !(opencreatmode & OPC_MODE_REPLACE)) if (exist > -1 && !(opencreatmode & OPC_MODE_REPLACE))
@ -1547,7 +1557,7 @@ static int nw_open_creat_file_or_dir(
nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb), nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb),
attrib, access_rights, creatmode, task)) > -1) { attrib, access_rights, creatmode, task)) > -1) {
fhandle = (uint32) result; fhandle = (uint32) result;
#if 0 #if 1 /* should be ok, 31-Jul-97 0.99.pl1 */
actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */ actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */
#endif #endif
if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE)) if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE))
@ -1572,32 +1582,136 @@ static int nw_open_creat_file_or_dir(
return(result); return(result);
} }
typedef struct {
int searchattrib;
uint8 *ubuf; /* userbuff */
} FUNC_SEARCH;
static int func_search_entry(DIR_BASE_ENTRY *dbe, int namespace,
uint8 *path, int len, int searchattrib,
int (*fs_func)(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs), FUNC_SEARCH *fs)
{
int result=-0xff;
FUNC_SEARCH fs_local;
DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT));
if (!fs) {
fs = &fs_local;
fs->ubuf = NULL;
}
fs->searchattrib = searchattrib;
ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258);
if (NULL != (ds->fdir = opendir(ds->unixname)) ) {
uint8 entry[257];
uint8 *pe=entry;
int have_wild = 0; /* do we have a wildcard entry */
int inode_search = 0;
uint8 *is_ap = NULL; /* one after point */
struct dirent *dirbuff = NULL;
int vol_options = get_volume_options(dbe->nwpath.volume);
ds->kpath = ds->unixname+strlen(ds->unixname);
*(ds->kpath) = '/';
*(++(ds->kpath)) = '\0';
dbe->locked++; /* lock dbe */
while (len--) {
uint8 c=*path++;
*pe++=c;
if (!have_wild) {
if (c==0xff) {
if (*path == '?' || *path == '*'
|| *path == 0xae || *path == 0xbf || *path==0xaa)
have_wild++;
} else if (c == '.') is_ap=pe;
}
}
*pe='\0';
if ((!have_wild) && is_ap && pe - is_ap == 3 && *is_ap== '_'
&& *(is_ap+1) == '_' && *(is_ap+2) == '_') {
*(is_ap -1) = '\0';
inode_search=atoi(entry);
*(is_ap -1) = '.';
}
if ( (namespace == NAME_DOS || namespace == NAME_OS2)
&& !(vol_options & VOL_OPTION_IGNCASE) ) {
if (vol_options & VOL_OPTION_DOWNSHIFT) {
down_fn(entry);
} else {
up_fn(entry);
}
}
while (NULL != (dirbuff=readdir(ds->fdir))) {
uint8 dname[257];
if (search_match( dirbuff,
vol_options,
namespace,
inode_search,
entry,
searchattrib,
dname,
ds)) {
int dest_entry = get_add_new_entry(dbe, namespace, dname, 0);
if (dest_entry > -1) {
int res = (*fs_func)(dir_base[dest_entry], fs);
if (res < 0) {
result=res;
break;
} else
result=0;
} else {
XDPRINTF((2, 0, "func_search_entry:Cannot add entry '%s'", entry));
}
}
} /* while */
*(ds->kpath) = '\0';
dbe->locked=0;
closedir(ds->fdir);
} else { /* if NULL != ds->fdir */
XDPRINTF((5, 0, "func_search_entry:could not opendir=`%s`", ds->unixname));
}
xfree(ds->unixname);
xfree(ds);
return(result);
}
static int delete_file_dir(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs)
/* callbackroutine */
{
uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2);
int result;
if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
result = rmdir(unname);
if (result < 0) {
switch (errno) {
case EEXIST: result=-0xa0; /* dir not empty */
default: result=-0x8a; /* No privilegs */
}
} else {
result = 0;
free_dbe_p(dbe);
}
} else {
if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname)))
free_dbe_p(dbe);
}
return(result);
}
static int nw_delete_file_dir(int namespace, int searchattrib, static int nw_delete_file_dir(int namespace, int searchattrib,
NW_HPATH *nwp) NW_HPATH *nwp)
{ {
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); uint8 search_entry[258];
int result = build_base(namespace, nwp, nwp->pathes, 1, search_entry);
if (result > -1) { if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result]; DIR_BASE_ENTRY *dbe=dir_base[result];
uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2);
if (get_volume_options(dbe->nwpath.volume) & if (get_volume_options(dbe->nwpath.volume) &
VOL_OPTION_READONLY) result = -0x8a; VOL_OPTION_READONLY) result = -0x8a;
else { else result=func_search_entry(dbe, namespace,
if (S_ISDIR(dbe->nwpath.statb.st_mode)) { search_entry, strlen(search_entry), searchattrib,
result = rmdir(unname); delete_file_dir, NULL);
if (result < 0) {
switch (errno) {
case EEXIST: result=-0xa0; /* dir not empty */
default: result=-0x8a; /* No privilegs */
}
} else {
result = 0;
free_dbe_p(dbe);
}
} else {
if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname)))
free_dbe_p(dbe);
}
}
} }
return(result); return(result);
} }
@ -1674,6 +1788,8 @@ static int nw_get_full_path_cookies(int namespace,
*(p++) = (uint8)l; *(p++) = (uint8)l;
memcpy(p, pp, l); memcpy(p, pp, l);
*(p+l)='\0'; *(p+l)='\0';
if (!namespace)
up_fn(p);
k++; k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p)); XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
p+=l; p+=l;
@ -2137,6 +2253,56 @@ static int code = 0;
} }
int fill_namespace_buffer(int volume, uint8 *rdata)
{
if (volume < used_nw_volumes) {
int voloptions=get_volume_options(volume);
uint8 *p=rdata;
int count=0;
*p++=5; /* we say 5 known namespaces (index 0=DOS .. 4=OS2 */
/* names */
*p++=3; memcpy(p,"DOS", 3); p+=3;
*p++=9; memcpy(p,"MACINTOSH", 9); p+=9;
*p++=3; memcpy(p,"NFS", 3); p+=3;
*p++=4; memcpy(p,"FTAM", 4); p+=4;
*p++=3; memcpy(p,"OS2", 3); p+=3;
/* datastreams */
*p++=3; /* we say 3 datastreams here */
*p++=NAME_DOS;
*p++=19; memcpy(p,"Primary Data Stream", 19); p+=19;
*p++=NAME_MAC;
*p++=23; memcpy(p,"Macintosh Resource Fork", 23); p+=23;
*p++=NAME_FTAM;
*p++=20; memcpy(p,"FTAM Extra Data Fork", 20); p+=20;
if (loaded_namespaces & VOL_NAMESPACE_DOS) ++count;
if (loaded_namespaces & VOL_NAMESPACE_OS2) ++count;
if (loaded_namespaces & VOL_NAMESPACE_NFS) ++count;
*p++ = count; /* loaded namespaces */
if (loaded_namespaces & VOL_NAMESPACE_DOS) *p++ = NAME_DOS;
if (loaded_namespaces & VOL_NAMESPACE_OS2) *p++ = NAME_OS2;
if (loaded_namespaces & VOL_NAMESPACE_NFS) *p++ = NAME_NFS;
count=0;
if (voloptions & VOL_NAMESPACE_DOS) ++count;
if (voloptions & VOL_NAMESPACE_OS2) ++count;
if (voloptions & VOL_NAMESPACE_NFS) ++count;
*p++ = count; /* volume namespaces */
if (voloptions & VOL_NAMESPACE_DOS) *p++ = NAME_DOS;
if (voloptions & VOL_NAMESPACE_OS2) *p++ = NAME_OS2;
if (voloptions & VOL_NAMESPACE_NFS) *p++ = NAME_NFS;
*p++ = 1; /* only one datastream */
*p++ = 0; /* DOS datastream */
return((int)(p-rdata));
} else return(-0x98);
}
int get_namespace_dir_entry(int volume, uint32 basehandle, int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata) int namspace, uint8 *rdata)
{ {

View File

@ -1,4 +1,4 @@
/* namspace.h 09-Nov-96 : NameSpace Services, mars_nwe */ /* namspace.h 01-Aug-97 : NameSpace Services, mars_nwe */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
@ -108,6 +108,7 @@ typedef struct {
extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task); extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task);
extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task); extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task);
extern int fill_namespace_buffer(int volume, uint8 *rdata);
extern int get_namespace_dir_entry(int volume, uint32 basehandle, extern int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata); int namspace, uint8 *rdata);

355
nwbind.c
View File

@ -1,5 +1,5 @@
/* nwbind.c */ /* nwbind.c */
#define REVISION_DATE "22-Jul-97" #define REVISION_DATE "26-Aug-97"
/* NCP Bindery SUB-SERVER */ /* NCP Bindery SUB-SERVER */
/* authentification and some message handling */ /* authentification and some message handling */
@ -22,6 +22,9 @@
#include "net.h" #include "net.h"
#include "nwdbm.h" #include "nwdbm.h"
#include "unxlog.h" #include "unxlog.h"
#include "nwbind.h"
#include "nwqueue.h"
#include "sema.h"
/* next should be '1', is for testing only */ /* next should be '1', is for testing only */
#define USE_PERMANENT_OUT_SOCKET 1 #define USE_PERMANENT_OUT_SOCKET 1
@ -64,17 +67,6 @@ static void write_to_nwserv(int what, int connection, int mode,
#define nwserv_down_server() \ #define nwserv_down_server() \
write_to_nwserv(0xffff, 0, 0, NULL, 0) write_to_nwserv(0xffff, 0, 0, NULL, 0)
typedef struct {
ipxAddr_t client_adr; /* address remote client */
uint32 object_id; /* logged object */
/* 0 = not logged in */
uint8 crypt_key[8]; /* password generation */
time_t t_login; /* login time */
uint8 message[60]; /* saved BCastmessage */
int active; /* 0=closed, 1= active */
int send_to_sock; /* this is the receiving sock */
int pid_nwconn; /* pid of user process nwconn */
} CONNECTION;
static int max_nw_vols=MAX_NW_VOLS; static int max_nw_vols=MAX_NW_VOLS;
static int max_connections=MAX_CONNECTIONS; static int max_connections=MAX_CONNECTIONS;
@ -163,13 +155,17 @@ static void open_clear_connection(int conn, int activate, uint8 *addr)
c->active = activate; c->active = activate;
c->message[0] = '\0'; c->message[0] = '\0';
c->t_login = 0; c->t_login = 0;
if (activate && addr) { if (activate && addr) {
memcpy(&(c->client_adr), addr, sizeof(ipxAddr_t)); memcpy(&(c->client_adr), addr, sizeof(ipxAddr_t));
c->send_to_sock = GET_BE16(addr+sizeof(ipxAddr_t)); c->send_to_sock = GET_BE16(addr+sizeof(ipxAddr_t));
c->pid_nwconn = GET_BE32(addr+sizeof(ipxAddr_t)+sizeof(uint16)); c->pid_nwconn = GET_BE32(addr+sizeof(ipxAddr_t)+sizeof(uint16));
} else { } else { /* down connection */
if (c->object_id) if (c->object_id)
write_utmp(0, conn+1, c->pid_nwconn, &(c->client_adr), NULL); write_utmp(0, conn+1, c->pid_nwconn, &(c->client_adr), NULL);
if (c->count_semas) {
clear_conn_semas(c);
}
} }
c->object_id = 0; c->object_id = 0;
} }
@ -221,29 +217,38 @@ static void handle_fxx(int gelen, int func)
uint8 len = *(requestdata+1); uint8 len = *(requestdata+1);
#endif #endif
uint8 ufunc = *(requestdata+2); uint8 ufunc;
uint8 *rdata = requestdata+3; uint8 *rdata;
uint8 completition = 0; uint8 completition = 0;
uint8 connect_status= 0; uint8 connect_status= 0;
int data_len = 0; int data_len = 0;
if (nw_debug > 1){ if (func==0x19) {
int j = gelen - sizeof(NCPREQUEST); ufunc = 0;
if (nw_debug){ rdata = requestdata;
if (func == 0x19) ufunc=0; } else if (func==0x20) {
XDPRINTF((1, 0, "NCP 0x%x REQUEST:ufunc:0x%x", func, ufunc)); ufunc = *requestdata;
if (j > 0){ rdata = requestdata+1;
uint8 *p=requestdata; } else {
XDPRINTF((1, 2, "len %d, DATA:", j)); ufunc = *(requestdata+2);
while (j--) { rdata = requestdata+3;
int c = *p++;
if (c > 32 && c < 127) XDPRINTF((1, 3, ",\'%c\'", (char) c));
else XDPRINTF((1, 3, ",0x%x", c));
}
XDPRINTF((1, 1, NULL));
}
}
} }
MDEBUG(D_BIND_REQ, {
int j = gelen - sizeof(NCPREQUEST);
XDPRINTF((1, 0, "NCP 0x%x REQUEST:ufunc:0x%x", func, ufunc));
if (j > 0){
uint8 *p=requestdata;
XDPRINTF((1, 2, "len %d, DATA:", j));
while (j--) {
int c = *p++;
if (c > 32 && c < 127) XDPRINTF((1, 3, ",\'%c\'", (char) c));
else XDPRINTF((1, 3, ",0x%x", c));
}
XDPRINTF((1, 1, NULL));
}
})
if (0x15 == func) { if (0x15 == func) {
switch (ufunc) { /* Messages */ switch (ufunc) { /* Messages */
case 0x0 : { /* Send Broadcast Message (old) */ case 0x0 : { /* Send Broadcast Message (old) */
@ -307,11 +312,13 @@ static void handle_fxx(int gelen, int func)
case 0x29 : { /* Read volume restrictions */ case 0x29 : { /* Read volume restrictions */
/* Returns 3 integers, uid, gid, 0=OK/1=Permission denied */ /* Returns 3 integers, uid, gid, 0=OK/1=Permission denied */
uint32 id = GET_BE32(rdata+1); uint32 id = GET_BE32(rdata+1);
internal_act=1;
if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)),
id, (char *) NULL) != 0) { id, (char *) NULL) != 0) {
completition = 0xff; completition = 0xff;
XDPRINTF((2, 0, "quota id-uid mapping failure %d 0x%x", ufunc, id)); XDPRINTF((2, 0, "quota id-uid mapping failure %d 0x%x", ufunc, id));
} }
internal_act=0;
/* OK if supervisor or trying to read (0x29) own limits */ /* OK if supervisor or trying to read (0x29) own limits */
if (act_c->object_id == 1 || if (act_c->object_id == 1 ||
(act_c->object_id == id && ufunc == 0x29)) (act_c->object_id == id && ufunc == 0x29))
@ -446,16 +453,20 @@ static void handle_fxx(int gelen, int func)
? (int) *rdata ? (int) *rdata
: act_connection) : act_connection)
: GET_32(rdata); : GET_32(rdata);
if (conn && --conn < max_connections if (conn >0 && conn <= max_connections
&& connections[conn].active ) { && connections[conn-1].active ) {
CONNECTION *cx=&(connections[conn]); CONNECTION *cx=&(connections[conn-1]);
data_len = sizeof(ipxAddr_t); data_len = sizeof(ipxAddr_t);
memcpy(responsedata, (char*)&(cx->client_adr), data_len); memcpy(responsedata, (char*)&(cx->client_adr), data_len);
if (ufunc==0x1a) { if (ufunc==0x1a) {
*(responsedata+data_len)=0x02; /* NCP connection */ *(responsedata+data_len)=0x02; /* NCP connection */
data_len++; data_len++;
} }
} else completition = 0xff; } else {
XDPRINTF((1, 0, "Get Connection Internet Adress, Conn:%d of %d failed",
conn, max_connections));
completition = 0xff;
}
} break; } break;
case 0x14 : { /* Login Objekt, unencrypted passwords */ case 0x14 : { /* Login Objekt, unencrypted passwords */
@ -1087,94 +1098,178 @@ static void handle_fxx(int gelen, int func)
completition=0xfb; completition=0xfb;
} break; } break;
case 0x66 : { /* Read Queue Current Status,old */
case 0x66 : { /* Read Queue Current Status,old */
/* !!!!!! TO DO */
NETOBJ obj;
struct XDATA { struct XDATA {
uint8 queue_id[4]; uint8 id[4];
uint8 status; uint8 status;
uint8 entries; uint8 entries;
uint8 servers; uint8 servers;
uint8 data[1]; /* server_id + server_station list */ uint8 data[1];
} *xdata = (struct XDATA*) responsedata; } *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
memset(xdata, 0, sizeof(struct XDATA)); int status;
U32_TO_BE32(obj.id, xdata->queue_id); int entries;
data_len = sizeof(struct XDATA); int servers;
XDPRINTF((1, 0, "TODO:READ QUEUE STATUS,old of Q=0x%lx", obj.id)); int server_ids[25];
int server_conns[25];
int result=nw_get_queue_status(q_id, &status, &entries,
&servers, server_ids, server_conns);
if (result>-1) {
int k;
uint8 *p=&(xdata->data[0]);
U32_TO_BE32(q_id, xdata->id);
xdata->status=status;
xdata->entries=entries;
xdata->servers=servers;
k=-1;
while (++k < servers) {
U32_TO_BE32(server_ids[k], p);
p+=4;
}
k=-1;
while (++k < servers) {
*p=(uint8) server_conns[k];
++p;
}
data_len=sizeof(struct XDATA)-1+5*servers;
} else
completition=(uint8)-result;
} }
break; break;
case 0x6A : /* Remove Job from Queue OLD */ case 0x6A : /* Remove Job from Queue OLD */
case 0x80 : { /* Remove Job from Queue NEW */ case 0x80 : { /* Remove Job from Queue NEW */
NETOBJ obj; uint32 q_id = GET_BE32(rdata);
uint32 jobnr = (ufunc == 0x6A) uint32 job_id = (ufunc == 0x6A)
? GET_BE16(rdata+4) ? GET_BE16(rdata+4)
: GET_BE32(rdata+4); : GET_BE32(rdata+4);
obj.id = GET_BE32(rdata); int result=nw_remove_job_from_queue(
XDPRINTF((1, 0, "TODO:Remove Job=%ld from Queue Q=0x%lx", jobnr, obj.id)); act_c->object_id,
completition=0xd5; /* no Queue Job */ q_id, job_id);
}break; if (result < 0)
completition=(uint8)-result;
case 0x6B : { /* Get Queue Job List, old */
/* !!!!!! TO DO */
NETOBJ obj;
obj.id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO:GET QUEUE JOB LIST,old of Q=0x%lx", obj.id));
memset(responsedata, 0, 2);
data_len = 2;
#if 0
completition=0xd5; /* no Queue Job */
#endif
} }
break; break;
case 0x6C : { /* Get Queue Job Entry */ case 0x6B : { /* Get Queue Job List, old */
/* !!!!!! TODO */ uint32 q_id=GET_BE32(rdata);
NETOBJ obj; int result=nw_get_queue_job_list_old(q_id, responsedata);
obj.id = GET_BE32(rdata); if (result > -1)
XDPRINTF((1, 0, "TODO: GET QUEUE JOB ENTRY of Q=0x%lx", obj.id)); data_len=result;
else
completition=(uint8)-result;
}
break;
completition=0xd5; /* no Queue Job */ case 0x6C : { /* Get Queue Job Entry old */
uint32 q_id = GET_BE32(rdata);
int job_id = GET_BE16(rdata+4);
int result=nw_get_q_job_entry(q_id, job_id,
responsedata, 1);
if (result > -1)
data_len=result;
else completition=(uint8)-result;
} }
break; break;
case 0x68: /* creat queue job and file old */ case 0x68: /* creat queue job and file old */
case 0x79: { /* creat queue job and file new */ case 0x79: { /* creat queue job and file new */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
uint8 *dir_name = responsedata+1; uint8 *q_job = rdata+4; /* jobsize = 256(old) or 280 */
int result = nw_get_q_dirname(q_id, dir_name); int result = nw_creat_queue_job(
if (result > -1) { act_connection, ncprequest->task,
*(dir_name-1) = result; act_c->object_id,
data_len = result+1; q_id, q_job,
} else { responsedata,
/* ufunc==0x68);
static int re=0x96; if (result > -1)
*/ data_len=result;
completition = (uint8) 0xd3; /* err no queue rights */ else
/* completition = (uint8) -result;
if (re == 0x96) re=0xd0; /*0xd3 err no queue rights */
else if (re < 0xff) ++re;
*/
}
} }
break; break;
case 0x69: /* close file and start queue old ?? */ case 0x69: /* close file and start queue old ?? */
case 0x7f: { /* close file and start queue */ case 0x7f: { /* close file and start queue */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
uint8 *prc = responsedata+1; uint32 job_id = (ufunc==0x69)
int result = nw_get_q_prcommand(q_id, prc); ? GET_BE16(rdata+4)
if (result > -1) { : GET_BE32(rdata+4);
*(prc-1) = result; int result = nw_close_queue_job(q_id, job_id,
data_len = result+1; responsedata);
} else completition = (uint8) 0xff; if (result > -1)
data_len=result;
else
completition = (uint8) -result;
} }
break; break;
case 0x6f : { /* attach server to queue */
/* from pserver */
uint32 q_id = GET_BE32(rdata);
int result=nw_attach_server_to_queue(
act_c->object_id,
act_connection,
q_id);
if (result < 0)
completition = (uint8) -result;
/* NO REPLY */
}
break;
case 0x70 : { /* detach server from queue */
/* from pserver */
uint32 q_id = GET_BE32(rdata);
int result=nw_detach_server_from_queue(
act_c->object_id,
act_connection,
q_id);
if (result < 0)
completition = (uint8) -result;
/* NO REPLY */
}
break;
case 0x78: /* Get Queue Job File Size (old) */
case 0x87: /* Get Queue Job File Size */
{
uint32 q_id = GET_BE32(rdata);
uint32 job_id = (ufunc==0x78)
? GET_BE16(rdata+4)
: GET_BE32(rdata+4);
int result = nw_get_queue_job_file_size(q_id, job_id);
if (result > -1) {
uint8 *p=responsedata;
U32_TO_BE32(q_id, p); p+=4;
if (ufunc==0x78) {
U16_TO_BE16(job_id, p); p+=2;
} else {
U32_TO_BE32(job_id, p); p+=4;
}
U32_TO_BE32(result, p); p+=4;
data_len=(int)(p-responsedata);
} else
completition = (uint8) -result;
}
break;
case 0x7c : { /* service queue job */
uint32 q_id = GET_BE32(rdata);
int type = GET_BE16(rdata+4);
int result=nw_service_queue_job(
act_c->object_id,
act_connection, ncprequest->task,
q_id, type, responsedata, 0);
if (result > -1)
data_len=result;
else
completition=(uint8)-result;
}
break;
case 0x7d : { /* Read Queue Current Status, new */ case 0x7d : { /* Read Queue Current Status, new */
NETOBJ obj;
struct XDATA { struct XDATA {
uint8 id[4]; /* queue id */ uint8 id[4]; /* queue id */
uint8 status[4]; /* &1 no station allowed */ uint8 status[4]; /* &1 no station allowed */
@ -1183,11 +1278,34 @@ static void handle_fxx(int gelen, int func)
uint8 entries[4]; /* current entries */ uint8 entries[4]; /* current entries */
uint8 servers[4]; /* current servers */ uint8 servers[4]; /* current servers */
} *xdata = (struct XDATA*) responsedata; } *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO:READ QUEUE STATUS NEW of Q=0x%lx", obj.id)); int status;
memset(xdata, 0, sizeof(*xdata)); int entries;
U32_TO_BE32(obj.id, xdata->id); int servers;
data_len=sizeof(struct XDATA); int server_ids[25];
int server_conns[25];
int result=nw_get_queue_status(q_id, &status, &entries,
&servers, server_ids, server_conns);
if (result>-1) {
int k;
uint8 *p=responsedata+sizeof(*xdata);
U32_TO_BE32(q_id, xdata->id);
U32_TO_32(status, xdata->status);
U32_TO_32(entries, xdata->entries);
U32_TO_32(servers, xdata->servers);
k=-1;
while (++k < servers) {
U32_TO_BE32(server_ids[k], p);
p+=4;
}
k=-1;
while (++k < servers) {
U32_TO_32(server_conns[k], p);
p+=4;
}
data_len=sizeof(struct XDATA)+8*servers;
} else
completition=(uint8)-result;
} break; } break;
case 0x81 : { /* Get Queue Job List */ case 0x81 : { /* Get Queue Job List */
@ -1203,6 +1321,37 @@ static void handle_fxx(int gelen, int func)
data_len=sizeof(struct XDATA); data_len=sizeof(struct XDATA);
}break; }break;
case 0x83: { /* finish servicing queue job */
uint32 q_id = GET_BE32(rdata);
uint32 job_id = GET_BE32(rdata+4);
#if 0
uint32 chargeinfo = GET_BE32(rdata+8);
#endif
int result = nw_finish_abort_queue_job(0,
act_c->object_id,
act_connection,
q_id, job_id);
if (result <0)
completition=(uint8) -result;
}break;
case 0x84: { /* abort servicing queue job */
uint32 q_id = GET_BE32(rdata);
uint32 job_id = GET_BE32(rdata+4);
int result = nw_finish_abort_queue_job(1,
act_c->object_id,
act_connection,
q_id, job_id);
if (result <0)
completition=(uint8) -result;
else {
memset(responsedata, 0, 2);
data_len=2;
}
}break;
case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */
XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV"));
/* !!!!!! TODO completition=0xc6 (no rights) */ /* !!!!!! TODO completition=0xc6 (no rights) */
@ -1283,14 +1432,18 @@ static void handle_fxx(int gelen, int func)
#if 0 #if 0
case 0xfd : /* Send Console Broadcast (new) */ case 0xfd : /* Send Console Broadcast (new) */
return(-1); /* nicht erkannt */ return(-1); /* nicht erkannt */
break; break;
#endif #endif
default : completition = 0xfb; /* not known here */ default : completition = 0xfb; /* not known here */
break;
} /* switch */ } /* switch */
} else if (func == 0x19) { /* logout */ } else if (func == 0x19) { /* logout */
write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL); write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL);
act_c->object_id = 0; /* not LOGIN */ act_c->object_id = 0; /* not LOGIN */
} else if (0x20 == func) { /* Semaphore */
int result = handle_func_0x20(act_c, rdata, ufunc, responsedata);
if (result > -1) data_len = result;
else completition=(uint8)-result;
} else completition = 0xfb; } else completition = 0xfb;
U16_TO_BE16(0x3333, ncpresponse->type); U16_TO_BE16(0x3333, ncpresponse->type);
@ -1346,8 +1499,11 @@ static void handle_bind_calls(uint8 *p)
static void reinit_nwbind(void) static void reinit_nwbind(void)
{ {
int org_internal_act=internal_act;
get_ini_debug(NWBIND); get_ini_debug(NWBIND);
internal_act=1;
(void)nw_fill_standard(NULL, NULL); (void)nw_fill_standard(NULL, NULL);
internal_act=org_internal_act;
sync_dbm(); sync_dbm();
} }
@ -1561,7 +1717,8 @@ int main(int argc, char *argv[])
t_close(ipx_out_fd); t_close(ipx_out_fd);
} }
} }
sync_dbm(); internal_act=1;
nw_exit_dbm();
xfree(connections); xfree(connections);
XDPRINTF((2,0, "LEAVE nwbind")); XDPRINTF((2,0, "LEAVE nwbind"));
return(0); return(0);

28
nwbind.h Normal file
View File

@ -0,0 +1,28 @@
/* nwbind.h 07-Aug-97 */
#ifndef _NWBIND_H_
#define _NWBIND_H_
#define MAX_SEMA_CONN 10 /* 10 Semaphore pre connection */
typedef struct {
int handle; /* semahore handle */
int opencount; /* times open */
} SEMA_CONN;
typedef struct {
ipxAddr_t client_adr; /* address remote client */
uint32 object_id; /* logged object */
/* 0 = not logged in */
uint8 crypt_key[8]; /* password generation */
time_t t_login; /* login time */
uint8 message[60]; /* saved BCastmessage */
int active; /* 0=closed, 1= active */
int send_to_sock; /* this is the receiving sock */
int pid_nwconn; /* pid of user process nwconn */
int count_semas; /* open semahores */
SEMA_CONN semas[MAX_SEMA_CONN];
} CONNECTION;
#endif

218
nwconn.c
View File

@ -1,4 +1,4 @@
/* nwconn.c 20-Jul-97 */ /* nwconn.c 14-Aug-97 */
/* one process / connection */ /* one process / connection */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -28,13 +28,10 @@
#include "nwvolume.h" #include "nwvolume.h"
#include "nwfile.h" #include "nwfile.h"
#include "connect.h" #include "connect.h"
#include "nwqueue.h" #include "nwqconn.h"
#include "namspace.h" #include "namspace.h"
#include "nwconn.h" #include "nwconn.h"
IPX_IO_RW ipx_io;
int use_ipx_io=0;
int act_connection = 0; int act_connection = 0;
int act_pid = 0; int act_pid = 0;
@ -92,8 +89,8 @@ typedef struct {
struct t_unitdata ud; struct t_unitdata ud;
ipxAddr_t to_addr; ipxAddr_t to_addr;
uint8 *recv_buf; /* complete data buf for burst read requests uint8 *recv_buf; /* complete data buf for burst read requests
* must be 24 byte more allocated * must be 24 byte more allocated
* than max_recv_size ! * than max_recv_size !
*/ */
@ -108,9 +105,9 @@ static BURST_W *burst_w=NULL;
static void set_program_title(char *s) static void set_program_title(char *s)
{ {
memset(prog_title, 0, 49); memset(prog_title, 0, 49);
if (s&&*s) if (s&&*s)
strmaxcpy(prog_title, s, 48); strmaxcpy(prog_title, s, 48);
else else
strcpy(prog_title, "()"); strcpy(prog_title, "()");
} }
@ -541,8 +538,8 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
} }
} }
completition = (uint8)-result; completition = (uint8)-result;
} else if (*p == 0x19){ } else if (*p == 0x19){
/* Set Directory Information /* Set Directory Information
* Modifies basic directory information as creation date and * Modifies basic directory information as creation date and
* directory rights mask. DOS namespace. * directory rights mask. DOS namespace.
*/ */
@ -550,8 +547,8 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 div[3]; /* 0x0, dlen, ufunc */
uint8 dir_handle; uint8 dir_handle;
uint8 creation_date[2]; uint8 creation_date[2];
uint8 creation_time[2]; uint8 creation_time[2];
uint8 owner_id[4]; uint8 owner_id[4];
uint8 new_max_rights; uint8 new_max_rights;
@ -633,17 +630,17 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
/* remove Vol restrictions for Obj */ /* remove Vol restrictions for Obj */
XDPRINTF((5, 0, "Remove vol restrictions")); XDPRINTF((5, 0, "Remove vol restrictions"));
return(-2); /* nwbind must do prehandling */ return(-2); /* nwbind must do prehandling */
} else if (*p == 0x25){ } else if (*p == 0x25){
/* Set Entry, Set Directory File Information /* Set Entry, Set Directory File Information
* sets or changes the file or directory information to the * sets or changes the file or directory information to the
* values entered in 'Change Bits'. * values entered in 'Change Bits'.
*/ */
/* NO REPLY */ /* NO REPLY */
/* ncopy use this call */ /* ncopy use this call */
/* TODO !!!!!!!!!!!!!!!!!!!! */ /* TODO !!!!!!!!!!!!!!!!!!!! */
do_druck++; do_druck++;
} else if (*p == 0x26) { /* Scan file or Dir for ext trustees */ } else if (*p == 0x26) { /* Scan file or Dir for ext trustees */
int sequenz = (int)*(p+2); /* trustee sequenz */ int sequenz = (int)*(p+2); /* trustee sequenz */
struct XDATA { struct XDATA {
@ -806,10 +803,18 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
} else completition = (uint8) -result; } else completition = (uint8) -result;
} else if (*p == 0x2e){ /* RENAME DATEI */ } else if (*p == 0x2e){ /* RENAME DATEI */
completition = 0xfb; /* TODO: !!! */ completition = 0xfb; /* TODO: !!! */
} else if (*p == 0x2f){ /* Fill namespace buffer */
completition = 0xfb; /* TODO: !!! */
/* ncopy use this call */
#if WITH_NAME_SPACE_CALLS #if WITH_NAME_SPACE_CALLS
} else if (*p == 0x2f){
/* Fill namespace buffer */
/* ncopy use this call */
int volume = (int) *(p+1);
/* (p+2) == 0xe4 or 0xe2 sometimes ???? */
int result=fill_namespace_buffer(
volume, responsedata);
if (result > -1) {
data_len = result;
} else completition = (uint8) -result;
} else if (*p == 0x30){ } else if (*p == 0x30){
/* Get Name Space Directory Entry */ /* Get Name Space Directory Entry */
int volume = (int) *(p+1); int volume = (int) *(p+1);
@ -929,11 +934,54 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
break; break;
case 0x68: /* create queue job and file old */ case 0x68: /* create queue job and file old */
case 0x69: /* close file and start queue old ?? */
case 0x79: /* create queue job and file */ case 0x79: /* create queue job and file */
case 0x7f: /* close file and start queue */
return(-2); /* nwbind must do prehandling */ return(-2); /* nwbind must do prehandling */
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 or 0x69 */
uint8 queue_id[4]; /* Queue ID */
uint8 job_id[4]; /* result from creat queue */
/* if 0x69 then only first 2 byte ! */
} *input = (struct INPUT *) (ncprequest);
uint32 q_id = GET_BE32(input->queue_id);
int job_id = (ufunc==0x69) ? GET_BE16(input->job_id)
: GET_BE32(input->job_id);
int result = close_queue_job(q_id, job_id);
if (result < 0) {
completition = (uint8)-result;
} else {
return(-2); /* nwbind must do next */
}
}
break;
case 0x7c : /* service queue job */
return(-2); /* nwbind must do prehandling */
case 0x83 : /* finish queue job */
case 0x84 : { /* abort queue job */
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */
uint8 func; /* 0x7f or 0x69 */
uint8 queue_id[4]; /* Queue ID */
uint8 job_id[4]; /* result from creat queue */
/* if 0x69 then only first 2 byte ! */
} *input = (struct INPUT *) (ncprequest);
uint32 q_id = GET_BE32(input->queue_id);
int job_id = GET_BE32(input->job_id);
int result = finish_abort_queue_job(q_id, job_id);
if (result <0)
completition=(uint8) -result;
else
return(-1); /* nwbind must do the rest */
}
break;
case 0xf3: { /* Map Direktory Number TO PATH */ case 0xf3: { /* Map Direktory Number TO PATH */
XDPRINTF((2,0, "TODO: Map Directory Number TO PATH")); XDPRINTF((2,0, "TODO: Map Directory Number TO PATH"));
completition = 0xff; completition = 0xff;
@ -957,6 +1005,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
break; break;
case 0x19 : /* logout, some of this call is handled in ncpserv. */ case 0x19 : /* logout, some of this call is handled in ncpserv. */
free_queue_jobs();
nw_free_handles(-1); nw_free_handles(-1);
set_default_guid(); set_default_guid();
nw_setup_home_vol(-1, NULL); nw_setup_home_vol(-1, NULL);
@ -965,6 +1014,9 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
return(-1); /* nwbind must do a little rest */ return(-1); /* nwbind must do a little rest */
break; break;
case 0x20 : /* Semaphore */
return(-1); /* handled by nwbind */
case 0x1a : /* lock file */ case 0x1a : /* lock file */
case 0x1e : /* unlock file */ case 0x1e : /* unlock file */
{ {
@ -1583,23 +1635,21 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
burst_w->max_send_size= burst_w->max_send_size=
min(max_burst_send_size, min(max_burst_send_size,
GET_BE32(input->max_recv_size)); GET_BE32(input->max_recv_size));
#if 1 /* MUST BE REMOVED LATER !!! */
/* we don't want fragment send packets */
if (burst_w->max_send_size >
burst_w->max_burst_data_size-8)
burst_w->max_send_size
=burst_w->max_burst_data_size-8;
#endif
burst_w->send_buf=xcmalloc(burst_w->max_send_size+8); burst_w->send_buf=xcmalloc(burst_w->max_send_size+8);
burst_w->max_recv_size= burst_w->max_recv_size=
min(max_burst_recv_size, min(max_burst_recv_size,
GET_BE32(input->max_send_size)); GET_BE32(input->max_send_size));
#if 1 /* MUST BE REMOVED LATER !!! */
/* we don't want fragmented receive packets */
if (burst_w->max_recv_size >
burst_w->max_burst_data_size-24)
burst_w->max_recv_size
=burst_w->max_burst_data_size-24;
#endif
burst_w->recv_buf=xcmalloc(burst_w->max_recv_size+24); burst_w->recv_buf=xcmalloc(burst_w->max_recv_size+24);
#if 0 #if 1
U32_TO_BE32(0x1600, burst_w->sendburst->delaytime); U32_TO_BE32(0x5ff22, burst_w->sendburst->delaytime);
#endif #endif
U32_TO_BE32(burst_w->max_recv_size, xdata->max_recv_size); U32_TO_BE32(burst_w->max_recv_size, xdata->max_recv_size);
U32_TO_BE32(burst_w->max_send_size, xdata->max_send_size); U32_TO_BE32(burst_w->max_send_size, xdata->max_send_size);
@ -1635,6 +1685,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
} /* switch function */ } /* switch function */
} else if (ncp_type == 0x1111) { } else if (ncp_type == 0x1111) {
free_queue_jobs();
(void) nw_init_connect(); (void) nw_init_connect();
last_sequence = -9999; last_sequence = -9999;
} else { } else {
@ -1771,7 +1822,7 @@ static void handle_after_bind()
case 0x68: /* create queue job and file old */ case 0x68: /* create queue job and file old */
case 0x79: { /* create queue job and file */ case 0x79: { /* create queue job and file */
/* nwbind must do prehandling */ /* nwbind made prehandling */
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */ uint8 packetlen[2]; /* low high */
@ -1779,22 +1830,15 @@ static void handle_after_bind()
uint8 queue_id[4]; /* Queue ID */ uint8 queue_id[4]; /* Queue ID */
uint8 queue_job[280]; /* oldsize is 256 */ uint8 queue_job[280]; /* oldsize is 256 */
} *input = (struct INPUT *) (ncprequest); } *input = (struct INPUT *) (ncprequest);
struct RINPUT { uint32 q_id = GET_BE32(input->queue_id);
uint8 dir_nam_len; /* len of dirname */ uint8 *qjob = bindresponse;
uint8 dir_name[1]; int result = creat_queue_job(q_id, qjob,
} *rinput = (struct RINPUT *) (bindresponse); responsedata,
int result = nw_creat_queue( (ufunc == 0x68) );
(int)ncpresponse->connection if (result > -1)
| (((int)ncpresponse->high_connection) << 8), data_len=result;
input->queue_id, else
input->queue_job, completition = (uint8) -result;
rinput->dir_name,
(int)rinput->dir_nam_len,
(ufunc == 0x68) );
if (!result) {
data_len = (ufunc == 0x68) ? 54 : 78;
memcpy(responsedata, input->queue_job, data_len);
} else completition= (uint8)-result;
} }
break; break;
@ -1803,22 +1847,47 @@ static void handle_after_bind()
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */ uint8 packetlen[2]; /* low high */
uint8 func; /* 0x7f or 0x6f */ uint8 func; /* 0x7f or 0x69 */
uint8 queue_id[4]; /* Queue ID */ uint8 queue_id[4]; /* Queue ID */
uint8 job_id[4]; /* result from creat queue */ uint8 job_id[4]; /* result from creat queue */
/* if 0x69 then only 2 byte ! */ /* if 0x69 then only 2 byte ! */
} *input = (struct INPUT *) (ncprequest); } *input = (struct INPUT *) (ncprequest);
struct RINPUT { struct RINPUT {
uint8 client_area[152];
uint8 prc_len; /* len of printcommand */ uint8 prc_len; /* len of printcommand */
uint8 prc[1]; /* printcommand */ uint8 prc[1]; /* printcommand */
} *rinput = (struct RINPUT *) (bindresponse); } *rinput = (struct RINPUT *) (bindresponse);
int result = nw_close_file_queue(input->queue_id, uint32 q_id = GET_BE32(input->queue_id);
input->job_id, int job_id = (ufunc==0x69) ? GET_BE16(input->job_id)
: GET_BE32(input->job_id);
int result = close_queue_job2(q_id, job_id,
rinput->client_area,
rinput->prc, rinput->prc,
rinput->prc_len); rinput->prc_len);
if (result < 0) completition = (uint8)-result; if (result < 0) completition = (uint8)-result;
} }
break; break;
case 0x7c : { /* service queue job */
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */
uint8 func; /* 0x7c */
uint8 queue_id[4]; /* Queue ID */
uint8 job_typ[2]; /* service typ */
} *input = (struct INPUT *) (ncprequest);
uint32 q_id = GET_BE32(input->queue_id);
uint8 *qjob = bindresponse;
int result = service_queue_job(q_id, qjob,
responsedata, 0);
if (result > -1)
data_len=result;
else
completition = (uint8) -result;
}
break;
default : completition = 0xfb; default : completition = 0xfb;
} }
} }
@ -1864,7 +1933,7 @@ static void handle_burst_response(uint32 offset, int size)
U16_TO_BE16(burst_w->burst_sequence, sb->burst_seq); U16_TO_BE16(burst_w->burst_sequence, sb->burst_seq);
U16_TO_BE16(burst_w->burst_sequence+1, sb->ack_seq); U16_TO_BE16(burst_w->burst_sequence+1, sb->ack_seq);
U32_TO_BE32(size, sb->burstsize); U32_TO_BE32(size, sb->burstsize);
while (size) { while (size) {
int sendsize=min(size, burst_w->max_burst_data_size); int sendsize=min(size, burst_w->max_burst_data_size);
int flags=0; int flags=0;
@ -1901,8 +1970,8 @@ static void handle_burst(BURSTPACKET *bp, int len)
struct REQ { struct REQ {
uint8 function[4]; /* lo-hi 1=READ, 2=WRITE */ uint8 function[4]; /* lo-hi 1=READ, 2=WRITE */
uint8 fhandle[4]; /* from open file */ uint8 fhandle[4]; /* from open file */
uint8 reserved1[6]; /* all zero */ uint8 reserved1[4]; /* all zero */
uint8 reserved2[2]; /* ??? c8,0 od. c9,f0 */ uint8 reserved2[4]; /* ??? c8,0 od. c9,f0 */
uint8 file_offset[4]; /* HI-LO */ uint8 file_offset[4]; /* HI-LO */
uint8 file_size [4]; /* HI-LO */ uint8 file_size [4]; /* HI-LO */
uint8 data[2]; /* only Write */ uint8 data[2]; /* only Write */
@ -1923,9 +1992,13 @@ static void handle_burst(BURSTPACKET *bp, int len)
*/ */
uint8 readbytes[4]; /* hi-lo */ uint8 readbytes[4]; /* hi-lo */
} *xdata= (struct XDATA*)burst_w->send_buf; } *xdata= (struct XDATA*)burst_w->send_buf;
int size = nw_read_file(fhandle, int zusatz = 0; /* (foffset & 1) ? 1 : 0; */
int size = nw_read_file(fhandle,
burst_w->send_buf+sizeof(struct XDATA), burst_w->send_buf+sizeof(struct XDATA),
fsize, foffset); fsize, foffset);
if (zusatz) {
XDPRINTF((1, 0, "foffset=%d, fsize=%d", foffset, fsize));
}
if (size > -1) { if (size > -1) {
U32_TO_32(0, xdata->resultcode); U32_TO_32(0, xdata->resultcode);
U32_TO_BE32(size, xdata->readbytes); U32_TO_BE32(size, xdata->readbytes);
@ -1948,7 +2021,10 @@ static void handle_burst(BURSTPACKET *bp, int len)
burst_w->burst_sequence = burstsequence; burst_w->burst_sequence = burstsequence;
handle_burst_response(0, sizeof(struct XDATA)); handle_burst_response(0, sizeof(struct XDATA));
} }
} else {
XDPRINTF((1, 0, "burst unknow function=0x%x", function));
} }
req->function[0]=0;
} else if (bp->flags & 0x80) { /* System Flag */ } else if (bp->flags & 0x80) { /* System Flag */
int missing=GET_BE16(bp->missing); int missing=GET_BE16(bp->missing);
uint8 *p=(uint8*)(bp+1); uint8 *p=(uint8*)(bp+1);
@ -2013,11 +2089,11 @@ static void set_sig(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 4 || 3!=sscanf(argv[3], "()INIT-:%x,%x,%x-", if (argc != 4 || 3!=sscanf(argv[3], "()INIT-:%x,%x,%x-",
&father_pid, &sock_nwbind, &sock_echo)) { &father_pid, &sock_nwbind, &sock_echo)) {
fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n"); fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n");
exit(1); exit(1);
} }
prog_title=argv[3]; prog_title=argv[3];
setuid(0); setuid(0);
setgid(0); setgid(0);
@ -2027,7 +2103,7 @@ int main(int argc, char **argv)
XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%d", XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%d",
father_pid, *(argv+2), act_connection)); father_pid, *(argv+2), act_connection));
adr_to_ipx_addr(&from_addr, *(argv+2)); adr_to_ipx_addr(&from_addr, *(argv+2));
if (nw_init_connect()) exit(1); if (nw_init_connect()) exit(1);
act_pid = getpid(); act_pid = getpid();
@ -2044,9 +2120,6 @@ int main(int argc, char **argv)
int conn = act_connection; int conn = act_connection;
int result = ioctl(0, SIOCIPXNCPCONN, &conn); int result = ioctl(0, SIOCIPXNCPCONN, &conn);
XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result)); XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result));
#if 0
if (result == 1) use_ipx_io++;
#endif
} }
# endif # endif
# endif # endif
@ -2069,27 +2142,10 @@ int main(int argc, char **argv)
ncpresponse->connection = (uint8)act_connection; ncpresponse->connection = (uint8)act_connection;
ncpresponse->high_connection = (uint8)(act_connection >> 8); ncpresponse->high_connection = (uint8)(act_connection >> 8);
ipx_io.ubuf = readbuff;
ipx_io.size = sizeof(readbuff);
ipx_io.ncp_resp = (char*)&ipxdata;
ipx_io.resp_size= sizeof(ipxdata);
ipx_io.fh_r = 0;
ipx_io.fd_r = -1;
ipx_io.fh_w = 0;
ipx_io.fd_w = -1;
set_sig(); set_sig();
while (fl_get_int >= 0) { while (fl_get_int >= 0) {
int data_len ; int data_len = read(0, readbuff, sizeof(readbuff));
#ifdef SIOCIPXNCPCONN
if (use_ipx_io)
data_len = ioctl(0, SIOCIPXNCPCONN+1, &ipx_io);
else
#endif
data_len = read(0, readbuff, sizeof(readbuff));
/* this read is a pipe or a socket read, /* this read is a pipe or a socket read,
* depending on CALL_NWCONN_OVER_SOCKET * depending on CALL_NWCONN_OVER_SOCKET
*/ */

View File

@ -1,23 +1,6 @@
/* nwconn.h 01-Aug-97 */
#ifndef _NWCONN_H_ #ifndef _NWCONN_H_
#define _NWCONN_H_ #define _NWCONN_H_
typedef struct {
int size; /* max. read size or write size */
char *ubuf; /* readbuf */
/* ------------------------------*/
char *ncp_resp; /* response packet */
int resp_size; /* max. size of response packet */
/* ------------------------------*/
int fh_r; /* NCP-Filehandle, read */
int fd_r; /* file-descriptor, read */
int fh_w; /* NCP-Filehandle, write */
int fd_w; /* file-descriptor, write */
} IPX_IO_RW;
extern IPX_IO_RW ipx_io;
extern int use_ipx_io;
extern int act_connection; extern int act_connection;
extern int act_pid; extern int act_pid;
#endif #endif

413
nwdbm.c
View File

@ -1,4 +1,4 @@
/* nwdbm.c 24-Jul-97 data base for mars_nwe */ /* nwdbm.c 16-Aug-97 data base for mars_nwe */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
#include "net.h" #include "net.h"
#include "nwdbm.h" #include "nwdbm.h"
#include "nwcrypt.h" #include "nwcrypt.h"
#include "nwqueue.h"
#include "dirent.h" #include "dirent.h"
#ifdef LINUX #ifdef LINUX
@ -60,7 +61,7 @@ uint32 network_serial_nmbr=(uint32)NETWORK_SERIAL_NMBR;
uint16 network_appl_nmbr=(uint16)NETWORK_APPL_NMBR; uint16 network_appl_nmbr=(uint16)NETWORK_APPL_NMBR;
static int entry8_flags = 0; static int entry8_flags = 0;
static uint8 *sys_unixname=NULL; /* Unixname of SYS: */ static uint8 *sys_unixname=NULL; /* Unixname of SYS: ends with '/' */
static int sys_unixnamlen=0; /* len of unixname */ static int sys_unixnamlen=0; /* len of unixname */
static int sys_downshift=0; /* is SYS downshift */ static int sys_downshift=0; /* is SYS downshift */
@ -153,10 +154,33 @@ void sync_dbm()
#ifdef USE_GDBM #ifdef USE_GDBM
# define firstkey() gdbm_firstkey(my_dbm) static datum firstkey(void)
# define nextkey(key) gdbm_nextkey(my_dbm, key) {
static char *last_dptr=NULL;
datum result=gdbm_firstkey(my_dbm);
if (last_dptr) free(last_dptr);
last_dptr=result.dptr;
return(result);
}
static datum nextkey(datum key)
{
static char *last_dptr=NULL;
datum result=gdbm_nextkey(my_dbm, key);
if (last_dptr) free(last_dptr);
last_dptr=result.dptr;
return(result);
}
static datum fetch(datum key)
{
static char *last_dptr=NULL;
datum result=gdbm_fetch(my_dbm, key);
if (last_dptr) free(last_dptr);
last_dptr=result.dptr;
return(result);
}
# define delete(key) gdbm_delete(my_dbm, key) # define delete(key) gdbm_delete(my_dbm, key)
# define fetch(key) gdbm_fetch(my_dbm, key)
# define store(key, content) gdbm_store(my_dbm, key, content, GDBM_REPLACE) # define store(key, content) gdbm_store(my_dbm, key, content, GDBM_REPLACE)
#else #else
# define firstkey() dbm_firstkey(my_dbm) # define firstkey() dbm_firstkey(my_dbm)
@ -218,11 +242,11 @@ int find_obj_id(NETOBJ *o)
int result; int result;
XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x", o->name,(int)o->type)); XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x", o->name,(int)o->type));
if ((result=handle_iobj(0, o)) == 0) { if ((result=handle_iobj(0, o)) == 0) {
result = -0xff;
if (!dbminit(FNOBJ)){ if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o; key.dptr = (char*)o;
data = fetch(key); data = fetch(key);
result = -0xff;
if (data.dptr != NULL){ if (data.dptr != NULL){
NETOBJ *obj=(NETOBJ*)data.dptr; NETOBJ *obj=(NETOBJ*)data.dptr;
XDPRINTF((3,0, "got OBJ name=%s, id = 0x%x", obj->name, (int)obj->id)); XDPRINTF((3,0, "got OBJ name=%s, id = 0x%x", obj->name, (int)obj->id));
@ -239,7 +263,7 @@ int find_obj_id(NETOBJ *o)
XDPRINTF((1,0, "OBJ Index '%s',0x%x, id=0x%x not found in OBJ data", XDPRINTF((1,0, "OBJ Index '%s',0x%x, id=0x%x not found in OBJ data",
o->name, (int)o->type, o->id)); o->name, (int)o->type, o->id));
} }
} else result = -0xff; }
dbmclose(); dbmclose();
if (!result) if (!result)
return(0); return(0);
@ -827,6 +851,17 @@ int nw_delete_property(int object_type,
return(result); return(result);
} }
int nw_is_member_in_set(uint32 obj_id, char *propname, uint32 member_id)
{
NETPROP prop;
int result;
strmaxcpy(prop.name, propname, sizeof(prop.name));
result=find_first_prop_id(&prop, obj_id);
if (!result)
result = prop_find_member(obj_id, (int)prop.id, prop.security, member_id);
return(result);
}
int nw_is_obj_in_set(int object_type, int nw_is_obj_in_set(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
uint8 *prop_name, int prop_namlen, uint8 *prop_name, int prop_namlen,
@ -998,8 +1033,9 @@ int nw_get_prop_val_str(uint32 q_id, char *propname, uint8 *buff)
if (result > -1) { if (result > -1) {
result=strlen(buff); result=strlen(buff);
XDPRINTF((5,0, "nw_get_prop_val_str:%s strlen=%d", propname, result)); XDPRINTF((5,0, "nw_get_prop_val_str:%s strlen=%d", propname, result));
} else } else {
XDPRINTF((5,0, "nw_get_prop_val_str:%s, result=-0x%x", propname, -result)); XDPRINTF((5,0, "nw_get_prop_val_str:%s, result=-0x%x", propname, -result));
}
return(result); return(result);
} }
@ -1078,6 +1114,19 @@ static int nw_create_obj_prop(uint32 obj_id, NETPROP *prop)
prop->id = p->id; prop->id = p->id;
prop->obj_id = obj_id; prop->obj_id = obj_id;
result = -0xed; /* Property exists */ result = -0xed; /* Property exists */
if (p->security != prop->security ||
p->flags != prop->flags) {
/* added 16-Aug-97 0.99.pl1 */
XDPRINTF((1, 0, "prop '%s' got new security/flag=0x%x / %d",
p->name, p->security, p->flags));
p->security=prop->security;
p->flags=prop->flags;
key.dsize = NETPROP_KEY_SIZE;
key.dptr = (char *)p;
data.dsize = sizeof(NETPROP);
data.dptr = (char *)p;
if (store(key, data)) result = -0xff;
}
break; break;
} else founds[p->id]++; } else founds[p->id]++;
} }
@ -1515,6 +1564,7 @@ int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr)
return(result); return(result);
} }
static int nw_new_add_prop_member(uint32 obj_id, char *propname, static int nw_new_add_prop_member(uint32 obj_id, char *propname,
int propflags, int propsecurity, int propflags, int propsecurity,
uint32 member_id) uint32 member_id)
@ -1534,13 +1584,19 @@ static int nw_new_add_prop_member(uint32 obj_id, char *propname,
return(result); return(result);
} }
static int xmkdir(char *unixname, int mode) int nwdbm_mkdir(char *unixname, int mode, int flags)
/* flags & 1 = set x permiss flag in upper dirs */
{ {
char *p=unixname; char *p=unixname;
while (NULL != (p=strchr(p+1, '/'))) { while (NULL != (p=strchr(p+1, '/'))) {
*p = '\0'; *p = '\0';
if (!mkdir(unixname, mode)) if (!mkdir(unixname, mode))
chmod(unixname, mode); chmod(unixname, mode);
else if (flags&1){
struct stat stb;
if (!stat(unixname, &stb))
chmod(unixname, stb.st_mode|0111);
}
*p='/'; *p='/';
} }
if (!mkdir(unixname, mode)) { if (!mkdir(unixname, mode)) {
@ -1557,7 +1613,7 @@ static void create_nw_db(char *fn, int always)
(void)get_div_pathes(fname, fn, 1, ".dir"); (void)get_div_pathes(fname, fn, 1, ".dir");
if (stat(fname, &stbuff)){ if (stat(fname, &stbuff)){
(void)get_div_pathes(fname, NULL, 1, NULL); (void)get_div_pathes(fname, NULL, 1, NULL);
xmkdir(fname, 0700); nwdbm_mkdir(fname, 0700, 0);
(void)get_div_pathes(fname, fn, 1, ".dir"); (void)get_div_pathes(fname, fn, 1, ".dir");
} }
if (always || stat(fname, &stbuff)){ if (always || stat(fname, &stbuff)){
@ -1573,30 +1629,54 @@ static void create_nw_db(char *fn, int always)
chmod(fname, 0600); chmod(fname, 0600);
} }
static void add_pr_queue(uint32 q_id, static void add_pr_queue(uint32 q_id,
char *q_name, char *q_directory, char *q_name, char *q_directory,
char *q_command, char *q_command,
uint32 su_id, uint32 ge_id) uint32 su_id, uint32 ge_id)
{ {
uint8 buf[300];
nw_new_obj(&q_id, q_name, 0x3, O_FL_STAT, 0x31);
if (!q_directory || !*q_directory) {
q_directory=buf;
sprintf(q_directory, "SYS:/SYSTEM/%08lX.QDR", q_id);
}
XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command)); XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command));
q_id = nw_new_obj_prop(q_id, NULL, 0, 0, 0,
nw_new_obj_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31,
"Q_DIRECTORY", P_FL_ITEM, 0x31, "Q_DIRECTORY", P_FL_ITEM, 0x31,
q_directory, strlen(q_directory), 1); q_directory, strlen(q_directory), 1);
/* this is mars_nwe own property to handle the print job !!! */ /* this is mars_nwe own property to handle the print job direct !!! */
nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 , if (q_command && *q_command) {
nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 ,
"Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x31, "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x31,
q_command, strlen(q_command), 1); q_command, strlen(q_command), 1);
}
nw_new_add_prop_member(q_id, "Q_USERS", P_FL_STAT, 0x31, ge_id); nw_new_add_prop_member(q_id, "Q_USERS", P_FL_STAT, 0x31, ge_id);
nw_new_add_prop_member(q_id, "Q_OPERATORS", P_FL_STAT, 0x31, su_id); nw_new_add_prop_member(q_id, "Q_OPERATORS", P_FL_STAT, 0x31, su_id);
#if 0
nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 , nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_SERVERS", P_FL_SET, 0x31, "Q_SERVERS", P_FL_SET, 0x31,
NULL, 0, 0); NULL, 0, 0);
#endif }
static void add_pr_server(uint32 ps_id,
char *ps_name,
char *ps_queue,
uint32 su_id, uint32 ge_id)
{
XDPRINTF((2,0, "ADD PS=%s, Q=%s", ps_name, ps_queue));
nw_new_obj(&ps_id, ps_name, 0x7, O_FL_STAT, 0x31);
nw_new_add_prop_member(ps_id, "PS_OPERATORS", P_FL_STAT, 0x31, su_id);
nw_new_add_prop_member(ps_id, "PS_USERS", P_FL_STAT, 0x31, ge_id);
if (ps_queue && *ps_queue) {
NETOBJ obj;
strmaxcpy((char*)obj.name, (char*)ps_queue, 47);
obj.type = 0x3; /* QUEUE */
if (!find_obj_id(&obj))
nw_new_add_prop_member(obj.id, "Q_SERVERS", P_FL_STAT, 0x31, ps_id);
}
} }
static void add_user_to_group(uint32 u_id, uint32 g_id) static void add_user_to_group(uint32 u_id, uint32 g_id)
@ -1610,7 +1690,7 @@ static void add_user_2_unx(uint32 u_id, char *unname)
{ {
if (unname && *unname) if (unname && *unname)
nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 , nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 ,
pn_unix_user, P_FL_ITEM, 0x33, pn_unix_user, P_FL_ITEM, 0x30,
(char*)unname, strlen(unname), 1); (char*)unname, strlen(unname), 1);
} }
@ -1703,7 +1783,7 @@ static int get_sys_unixname(uint8 *unixname, uint8 *sysname, uint8 *sysentry)
*(pp+1) = '\0'; *(pp+1) = '\0';
if (stat(unixname, &statb) < 0) if (stat(unixname, &statb) < 0)
xmkdir(unixname, 0777); nwdbm_mkdir(unixname, 0777, 1);
if (stat(unixname, &statb) < 0 || !S_ISDIR(statb.st_mode)) { if (stat(unixname, &statb) < 0 || !S_ISDIR(statb.st_mode)) {
errorp(1, "No good SYS", "unix name='%s'", unixname); errorp(1, "No good SYS", "unix name='%s'", unixname);
@ -1720,13 +1800,14 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags,
/* flags & 1 = fn will be appended to unixname */ /* flags & 1 = fn will be appended to unixname */
/* flags & 2 = always modify uid/gid, permission */ /* flags & 2 = always modify uid/gid, permission */
/* flags & 4 = always add x flag to upper dirs */
{ {
struct stat stb; struct stat stb;
strcpy((char*)pp, fn); strcpy((char*)pp, fn);
if (downshift) downstr(pp); if (downshift) downstr(pp);
else upstr(pp); else upstr(pp);
if (stat(unixname, &stb) < 0) { if (stat(unixname, &stb) < 0) {
if (xmkdir(unixname, permiss)< 0) if (nwdbm_mkdir(unixname, permiss, (flags&4) ? 1 : 0)< 0)
errorp(1, "mkdir error", "fname='%s'", unixname); errorp(1, "mkdir error", "fname='%s'", unixname);
else { else {
chmod(unixname, permiss); chmod(unixname, permiss);
@ -1734,10 +1815,22 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags,
chown(unixname, uid, gid); chown(unixname, uid, gid);
XDPRINTF((1, 0, "Created dir '%s'", unixname)); XDPRINTF((1, 0, "Created dir '%s'", unixname));
} }
} else if (flags&2) { } else {
chmod(unixname, permiss); if (flags&4) { /* add 'x' flag */
if (uid >-1 && gid > -1) char *p=unixname;
chown(unixname, uid, gid); while (NULL != (p=strchr(p+1, '/'))) {
struct stat stb;
*p = '\0';
if (!stat(unixname, &stb))
chmod(unixname, stb.st_mode|0111);
*p='/';
}
}
if (flags&2) {
chmod(unixname, permiss);
if (uid >-1 && gid > -1)
chown(unixname, uid, gid);
}
} }
if (flags&1) { if (flags&1) {
pp += strlen(pp); pp += strlen(pp);
@ -1748,24 +1841,30 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags,
return(pp); return(pp);
} }
static void correct_user_dirs(uint32 objid, int uid, int gid) static void correct_user_dirs(uint32 objid, uint8 *objname, int uid, int gid)
{ {
uint8 fndir[512]; uint8 fndir[512];
uint8 buf1[20];
uint8 *p = fndir+sys_unixnamlen; uint8 *p = fndir+sys_unixnamlen;
uint8 *pp; uint8 *pp;
uint8 *p1;
int l; int l;
DIR *f; DIR *f;
memcpy(fndir, sys_unixname, sys_unixnamlen); memcpy(fndir, sys_unixname, sys_unixnamlen);
/* SYS/MAIL */ /* SYS/MAIL */
l=sprintf(p,"/mail/%x", (int)objid); memcpy(p,"/mail/", 6);
pp=p+l; p1=p+6;
if (!sys_downshift) l=sprintf(buf1,"../%x", (int)objid)-3;
memcpy(p1, buf1+3, l+1);
pp=p1+l;
*pp='\0';
if (!sys_downshift) {
upstr(p); upstr(p);
upstr(buf1);
}
(void)mkdir(fndir, 0733); (void)mkdir(fndir, 0733);
(void)chmod(fndir, 0733); (void)chmod(fndir, 0733);
(void)chown(fndir, uid, gid); (void)chown(fndir, uid, gid);
if ((f=opendir(fndir)) != (DIR*)NULL) { if ((f=opendir(fndir)) != (DIR*)NULL) {
struct dirent* dirbuff; struct dirent* dirbuff;
*pp='/'; *pp='/';
@ -1778,24 +1877,35 @@ static void correct_user_dirs(uint32 objid, int uid, int gid)
} }
} }
} }
*pp='\0';
closedir(f); closedir(f);
} }
memcpy(p1, "user/", 5);
strmaxcpy(p1+5, objname, 47);
if (!sys_downshift)
upstr(p1);
else
downstr(p1+5);
symlink(buf1, fndir);
} }
void test_ins_unx_user(uint32 id) void test_ins_unx_user(uint32 id)
{ {
NETOBJ obj; NETOBJ obj;
obj.id = id; obj.id = id;
if ((MYPASSWD*)NULL == nw_getpwnam(id) && !nw_get_obj(&obj)){ if (!nw_get_obj(&obj)){
struct passwd *pw; MYPASSWD *mpw=nw_getpwnam(id);
uint8 unxname[50]; if ((MYPASSWD*)NULL == mpw){
xstrcpy(unxname, obj.name); struct passwd *pw;
downstr(unxname); uint8 unxname[50];
pw = getpwnam(unxname); xstrcpy(unxname, obj.name);
if (NULL != pw && pw->pw_uid) { /* only non root user */ downstr(unxname);
add_user_2_unx(id, unxname); pw = getpwnam(unxname);
correct_user_dirs(id, pw->pw_uid, pw->pw_gid); if (NULL != pw && pw->pw_uid) { /* only non root user */
add_user_2_unx(id, unxname);
correct_user_dirs(id, obj.name, pw->pw_uid, pw->pw_gid);
}
} else if (mpw->pw_uid){
correct_user_dirs(id, obj.name, mpw->pw_uid, mpw->pw_gid);
} }
} }
} }
@ -1806,12 +1916,10 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
char serverna[MAX_SERVER_NAME+2]; char serverna[MAX_SERVER_NAME+2];
uint32 su_id = 0x00000001; uint32 su_id = 0x00000001;
uint32 ge_id = 0x01000001; uint32 ge_id = 0x01000001;
uint32 serv_id = 0x03000001; uint32 server_id= 0x03000001;
uint32 q1_id = 0x0E000001; uint32 q1_id = 0x0E000001;
#ifdef _MAR_TESTS_1 uint32 ps1_id = 0x0F000001;
uint32 pserv_id = 0L; FILE *f = open_nw_ini();
#endif
FILE *f = open_nw_ini();
int auto_ins_user = 0; int auto_ins_user = 0;
char auto_ins_passwd[100]; char auto_ins_passwd[100];
int make_tests = 1; int make_tests = 1;
@ -1844,13 +1952,16 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
} else if (8 == what) { /* entry8_flags */ } else if (8 == what) { /* entry8_flags */
entry8_flags = hextoi((char*)buff); entry8_flags = hextoi((char*)buff);
} else if (21 == what) { /* QUEUES */ } else if (21 == what) { /* QUEUES */
char name[100]; char name[200];
char directory[200]; char directory[200];
char command[200]; char command[200];
char *p=buff; char *p=buff;
char *pp=name; char *pp=name;
char c; char c;
int state=0; int state=0;
name[0]='\0';
directory[0]='\0';
command[0]='\0';
while (0 != (c = *p++)) { while (0 != (c = *p++)) {
if (c == 32 || c == '\t') { if (c == 32 || c == '\t') {
if (!(state & 1)) { if (!(state & 1)) {
@ -1862,21 +1973,59 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
if (state == 1) { if (state == 1) {
pp=directory; pp=directory;
state++; state++;
} else { } else if (state==3) {
strcpy(command, p-1); strcpy(command, p-1);
if (*command) state++;
break; break;
} }
} }
*pp++ = c; *pp++ = c;
} }
} }
*pp='\0'; *pp='\0';
if (state == 4) { if (*name) {
upstr(name); upstr(name);
if (directory[0]=='-' && directory[1]=='\0')
directory[0]='\0';
if (command[0]=='-' && command[1]=='\0')
command[0]='\0';
add_pr_queue(q1_id, name, directory, command, su_id, ge_id); add_pr_queue(q1_id, name, directory, command, su_id, ge_id);
q1_id++; q1_id++;
} }
} else if (22 == what) { /* PSERVER */
char name[200];
char queue[200];
char *p=buff;
char *pp=name;
char c;
int state=0;
name[0]='\0';
queue[0]='\0';
while (0 != (c = *p++)) {
if (c == 32 || c == '\t') {
if (!(state & 1)) {
*pp = '\0';
state++;
}
} else {
if (state & 1){
if (state == 1) {
pp=queue;
state++;
} else break;
}
*pp++ = c;
}
}
*pp='\0';
if (*name) {
upstr(name);
upstr(queue);
add_pr_server(ps1_id, name, queue, su_id, ge_id);
ps1_id++;
}
} else if (12 == what || 13 == what || 14 == what) { } else if (12 == what || 13 == what || 14 == what) {
/* SUPERVISOR, OTHERS and GROUPS*/ /* SUPERVISOR, OTHERS and GROUPS*/
char nname[100]; char nname[100];
@ -1927,10 +2076,12 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
fclose(f); fclose(f);
} }
if (servername && adr) { if (servername && adr) {
strmaxcpy(serverna, servername, MAX_SERVER_NAME); strmaxcpy(serverna, servername, MAX_SERVER_NAME);
upstr(serverna); upstr(serverna);
nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, nw_new_obj_prop(server_id, serverna, 0x4, O_FL_DYNA, 0x40,
"NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40,
(char*)adr, sizeof(ipxAddr_t), 1); (char*)adr, sizeof(ipxAddr_t), 1);
@ -1940,6 +2091,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
(char*)adr, sizeof(ipxAddr_t), 1); (char*)adr, sizeof(ipxAddr_t), 1);
#endif #endif
} }
if (auto_ins_user) { if (auto_ins_user) {
/* here Unix users will be inserted automaticly as mars_nwe users */ /* here Unix users will be inserted automaticly as mars_nwe users */
struct passwd *pw; struct passwd *pw;
@ -1989,83 +2141,90 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
memset(auto_ins_passwd, 0, sizeof(auto_ins_passwd)); memset(auto_ins_passwd, 0, sizeof(auto_ins_passwd));
if (*sysentry) { if (*sysentry) {
int result = 0; uint8 unixname[512];
uint8 sysname[256];
int result = get_sys_unixname(unixname, sysname, sysentry);
int downshift = (result & 1);
int unlen = strlen(unixname);
if (result < 0) return(-1);
new_str(sys_unixname, unixname);
sys_downshift = downshift;
sys_unixnamlen = unlen;
if (make_tests) { if (make_tests) {
uint8 unixname[512]; uint32 objs[LOC_MAX_OBJS];
uint8 maildir[512]; uint8 maildir[512];
uint8 sysname[256]; int ocount=0;
result = get_sys_unixname(unixname, sysname, sysentry); uint8 *pp = unixname+unlen;
if (result > -1) { uint8 *ppp = maildir+unlen;
uint32 objs[2000]; /* max. 2000 User should be enough :) */ memcpy(maildir, unixname, unlen+1);
int ocount=0;
int downshift = (result & 1);
int unlen = strlen(unixname);
uint8 *pp = unixname+unlen;
uint8 *ppp = maildir+unlen;
memcpy(maildir, unixname, unlen+1);
new_str(sys_unixname, unixname); test_add_dir(unixname, pp, 4, downshift,0755, 0,0, "LOGIN");
sys_downshift=downshift; test_add_dir(unixname, pp, 0, downshift,0755, 0,0, "SYSTEM");
sys_unixnamlen=unlen; test_add_dir(unixname, pp, 0, downshift,0755, 0,0, "PUBLIC");
/* ----- */
ppp=test_add_dir(maildir, ppp, 1, downshift,0755, 0,0, "MAIL");
test_add_dir(maildir, ppp, 0, downshift,0755, 0,0, "USER");
test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "LOGIN"); if (!dbminit(FNOBJ)){
test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "SYSTEM"); for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "PUBLIC"); data = fetch(key);
ppp=test_add_dir(maildir, ppp, 1, downshift,0777, 0,0, "MAIL"); if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr;
if (!dbminit(FNOBJ)){ if (obj->type == 1 || obj->type == 3) {
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { objs[ocount++] = obj->id;
data = fetch(key); if (ocount == LOC_MAX_OBJS) break;
if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr;
if (obj->type == 1 || obj->type == 3) {
objs[ocount++] = obj->id;
if (ocount == 2000) break;
}
} }
} }
} }
dbmclose(); }
dbmclose();
while (ocount--) { while (ocount--) {
NETOBJ obj; NETOBJ obj;
obj.id = objs[ocount]; obj.id = objs[ocount];
nw_get_obj(&obj); nw_get_obj(&obj);
if (obj.type == 1) { if (obj.type == 1) {
char sx[20]; char sx[20];
int gid; int gid;
int uid; int uid;
sprintf(sx, "%x", (int)obj.id); sprintf(sx, "../%x", (int)obj.id);
if (!get_guid(&gid, &uid, obj.id, NULL)) if (!get_guid(&gid, &uid, obj.id, NULL)) {
test_add_dir(maildir, ppp, 2, downshift, 0733, gid, uid, sx); test_add_dir(maildir, ppp, 2, downshift, 0733, gid, uid, sx+3);
else memcpy(ppp, "user/", 5);
errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name); strmaxcpy(ppp+5, obj.name, 47);
if (downshift) downstr(ppp+5);
else upstr(ppp);
unlink(maildir);
symlink(sx, maildir);
*ppp='\0';
} else
errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name);
} else if (obj.type == 3) { /* print queue */ } else if (obj.type == 3) { /* print queue */
uint8 buff[300]; uint8 buff[300];
char *p; char *p;
int result=nw_get_q_dirname(obj.id, buff); result=nw_get_q_dirname(obj.id, buff);
upstr(buff); upstr(buff);
if (result > -1 && NULL != (p=strchr(buff, ':')) ) { if (result > -1 && NULL != (p=strchr(buff, ':')) ) {
*p++='\0'; *p++='\0';
if (!strcmp(buff, sysname)) { if (!strcmp(buff, sysname)) {
test_add_dir(unixname, pp, 2, downshift, 0770, 0, 0, p); test_add_dir(unixname, pp, 2|4, downshift, 0775, 0, 0, p);
} else
errorp(0, "Warning:queue dir not on first SYS",
"Queue=%s, Volume=%s", obj.name, sysname);
} else } else
errorp(0, "Cannot get queue dir", "Queue=%s", obj.name); errorp(0, "queue dir not on SYS",
} "Queue=%s, Volume=%s", obj.name, sysname);
} else
errorp(0, "Cannot get queue dir", "Queue=%s", obj.name);
} }
result = 0;
} }
} }
return(result); init_queues(sys_unixname, sys_unixnamlen, sys_downshift, sysname); /* nwqueue.c */
return(0);
} }
return(-1); return(-1);
} }
int nw_init_dbm(char *servername, ipxAddr_t *adr) static void nw_init_dbm_1(char *servername, ipxAddr_t *adr)
/* /*
* routine inits bindery * routine inits bindery
* all dynamic objects and properties will be deleted. * all dynamic objects and properties will be deleted.
@ -2122,11 +2281,22 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr)
dbmclose(); dbmclose();
while (anz--) /* now delete dynamic properties */ while (anz--) /* now delete dynamic properties */
loc_delete_property(objs[anz], (char*)NULL, props[anz], 1); loc_delete_property(objs[anz], (char*)NULL, props[anz], 1);
anz = nw_fill_standard(servername, adr);
sync_dbm();
return(anz);
} }
int nw_init_dbm(char *servername, ipxAddr_t *adr)
{
int result;
nw_init_dbm_1(servername, adr);
result = nw_fill_standard(servername, adr);
sync_dbm();
return(result);
}
void nw_exit_dbm(void)
{
exit_queues();
sync_dbm();
}
#if 0 #if 0
#define MAX_OBJ_IDS 100000 /* should be enough */ #define MAX_OBJ_IDS 100000 /* should be enough */
@ -2392,14 +2562,3 @@ int do_import_dbm(char *path)
return(result); return(result);
} }
/* ============> this should becomes queue.c or similar < ============== */
int nw_get_q_dirname(uint32 q_id, uint8 *buff)
{
return(nw_get_prop_val_str(q_id, "Q_DIRECTORY", buff));
}
int nw_get_q_prcommand(uint32 q_id, uint8 *buff)
{
return(nw_get_prop_val_str(q_id, "Q_UNIX_PRINT", buff));
}

12
nwdbm.h
View File

@ -1,4 +1,4 @@
/* nwdbm.h 17-Apr-97 */ /* nwdbm.h 24-Aug-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -120,6 +120,8 @@ extern int nw_delete_property(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
uint8 *prop_name, int prop_namlen); uint8 *prop_name, int prop_namlen);
extern int nw_is_member_in_set(uint32 obj_id, char *propname,
uint32 member_id);
extern int nw_is_obj_in_set(int object_type, extern int nw_is_obj_in_set(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
@ -162,6 +164,8 @@ extern int nw_scan_property(NETPROP *prop,
int prop_namlen, int prop_namlen,
uint32 *last_scan); uint32 *last_scan);
extern int nw_get_prop_val_str(uint32 q_id, char *propname, uint8 *buff);
extern int nw_create_obj(NETOBJ *obj, uint32 wanted_id); extern int nw_create_obj(NETOBJ *obj, uint32 wanted_id);
@ -193,15 +197,17 @@ extern int nw_keychange_passwd(uint32 obj_id,
extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr); extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr);
extern int nw_get_q_dirname(uint32 q_id, uint8 *buff);
extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff);
extern int nwdbm_mkdir(char *unixname, int mode, int flags);
extern void test_ins_unx_user(uint32 id); extern void test_ins_unx_user(uint32 id);
extern int test_allow_password_change(uint32 id); extern int test_allow_password_change(uint32 id);
extern int nw_fill_standard(char *servername, ipxAddr_t *adr); extern int nw_fill_standard(char *servername, ipxAddr_t *adr);
extern int nw_init_dbm(char *servername, ipxAddr_t *adr); extern int nw_init_dbm(char *servername, ipxAddr_t *adr);
extern void nw_exit_dbm(void);
extern int do_export_dbm(char *path); extern int do_export_dbm(char *path);
extern int do_import_dbm(char *path); extern int do_import_dbm(char *path);
#endif #endif

114
nwfile.c
View File

@ -1,4 +1,4 @@
/* nwfile.c 25-Jul-97 */ /* nwfile.c 26-Aug-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -41,11 +41,20 @@ void sig_bus_mmap(int rsig)
static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN]; static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN];
#define HOFFS 0 #define HOFFS 0
#define USE_NEW_FD 1
static int count_fhandles=0; static int count_fhandles=0;
#if USE_NEW_FD
static int last_fhandle=HOFFS;
#endif
static int new_file_handle(uint8 *unixname, int task) static int new_file_handle(uint8 *unixname, int task)
{ {
int fhandle = HOFFS -1; #if USE_NEW_FD
int fhandle= -1 + last_fhandle++;
#else
int fhandle=HOFFS-1;
#endif
FILE_HANDLE *fh=NULL; FILE_HANDLE *fh=NULL;
while (++fhandle < count_fhandles) { while (++fhandle < count_fhandles) {
fh=&(file_handles[fhandle]); fh=&(file_handles[fhandle]);
@ -54,13 +63,27 @@ static int new_file_handle(uint8 *unixname, int task)
break; break;
} else fh=NULL; } else fh=NULL;
} }
if (fh == NULL) { if (fh == NULL) {
if (count_fhandles < MAX_FILE_HANDLES_CONN) { if (count_fhandles < MAX_FILE_HANDLES_CONN) {
fh=&(file_handles[count_fhandles]); fh=&(file_handles[count_fhandles]);
fhandle = ++count_fhandles; fhandle = ++count_fhandles;
} else { } else {
XDPRINTF((1, 0, "No more free file handles")); #if USE_NEW_FD
return(0); /* no free handle anymore */ last_fhandle=HOFFS+1;
fhandle=HOFFS-1;
while (++fhandle < count_fhandles) {
fh=&(file_handles[fhandle]);
if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */
fhandle++;
break;
} else fh=NULL;
}
#endif
if (fh == NULL) {
XDPRINTF((1, 0, "No more free file handles"));
return(0); /* no free handle anymore */
}
} }
} }
/* init handle */ /* init handle */
@ -74,31 +97,12 @@ static int new_file_handle(uint8 *unixname, int task)
fh->f = NULL; fh->f = NULL;
XDPRINTF((5, 0, "new_file_handle=%d, count_fhandles=%d, fn=%s", XDPRINTF((5, 0, "new_file_handle=%d, count_fhandles=%d, fn=%s",
fhandle, count_fhandles, unixname)); fhandle, count_fhandles, unixname));
if (fhandle == ipx_io.fh_r){
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
}
if (fhandle == ipx_io.fh_w){
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
}
return(fhandle); return(fhandle);
} }
static int free_file_handle(int fhandle) static int free_file_handle(int fhandle)
{ {
int result=-0x88; int result=-0x88;
if (fhandle == ipx_io.fh_r){
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
}
if (fhandle == ipx_io.fh_w){
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
}
if (fhandle > HOFFS && (fhandle <= count_fhandles)) { if (fhandle > HOFFS && (fhandle <= count_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]); FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) { if (fh->fd > -1) {
@ -125,11 +129,13 @@ static int free_file_handle(int fhandle)
} }
} }
fh->fd = -1; fh->fd = -1;
#if !USE_NEW_FD
while (count_fhandles > fhandle while (count_fhandles > fhandle
&& file_handles[count_fhandles-1].fd == -1 && file_handles[count_fhandles-1].fd == -1
&& !(file_handles[count_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) { && !(file_handles[count_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) {
count_fhandles--; count_fhandles--;
} }
#endif
result=0; result=0;
} }
XDPRINTF((5, 0, "free_file_handle=%d, count_fhandles=%d, result=%d", XDPRINTF((5, 0, "free_file_handle=%d, count_fhandles=%d, result=%d",
@ -148,6 +154,9 @@ void init_file_module(int task)
while (k++ < count_fhandles) while (k++ < count_fhandles)
free_file_handle(k); free_file_handle(k);
count_fhandles = HOFFS; count_fhandles = HOFFS;
#if USE_NEW_FD
last_fhandle = HOFFS;
#endif
} else { } else {
/* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */ /* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */
while (k++ < count_fhandles) { while (k++ < count_fhandles) {
@ -157,10 +166,6 @@ void init_file_module(int task)
} }
} }
} }
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
} }
static int xsetegid(gid_t gid) static int xsetegid(gid_t gid)
@ -185,8 +190,9 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
* creatmode: 0 = open * creatmode: 0 = open
* | 1 = creat (ever) * | 1 = creat (ever)
* | 2 = creatnew ( creat if not exist ) * | 2 = creatnew ( creat if not exist )
* & 4 == save handle (creat) * ---------
* & 8 == ignore rights (create ever) * & 4 == save handle (not reuse)
* & 8 == ignore rights (try to open as root)
* attrib ?? * attrib ??
* *
* access: 0x1=read, * access: 0x1=read,
@ -210,7 +216,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
*/ */
{ {
int fhandle = new_file_handle(unixname, task); int fhandle = new_file_handle(unixname, task);
int dowrite = ((access & 2) || creatmode) ? 1 : 0; int dowrite = ((access & 2) || (creatmode & 3) ) ? 1 : 0;
if (fhandle > HOFFS){ if (fhandle > HOFFS){
FILE_HANDLE *fh=&(file_handles[fhandle-1]); FILE_HANDLE *fh=&(file_handles[fhandle-1]);
int completition = 0; /* first ok */ int completition = 0; /* first ok */
@ -220,7 +226,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
int did_grpchange = 0; int did_grpchange = 0;
if (dowrite && (voloptions & VOL_OPTION_READONLY)) { if (dowrite && (voloptions & VOL_OPTION_READONLY)) {
completition = (creatmode) ? -0x84 : -0x94; completition = (creatmode&3) ? -0x84 : -0x94;
} else if (acc > -1) { } else if (acc > -1) {
/* do exist */ /* do exist */
if (!S_ISDIR(stbuff->st_mode)) { if (!S_ISDIR(stbuff->st_mode)) {
@ -238,9 +244,9 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
XDPRINTF((1, 0, "Uses strange open comp. mode for file `%s`", XDPRINTF((1, 0, "Uses strange open comp. mode for file `%s`",
fh->fname)); fh->fname));
} else } else
completition = (creatmode) ? -0x84 : -0x94; completition = (creatmode&3) ? -0x84 : -0x94;
} else } else
completition = (creatmode) ? -0x84 : -0x94; completition = (creatmode&3) ? -0x84 : -0x94;
} else if (!(acc & R_OK) && !(creatmode & 0x8) ) } else if (!(acc & R_OK) && !(creatmode & 0x8) )
completition = -0x93; completition = -0x93;
@ -267,7 +273,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
} }
} else } else
completition= -0xff; completition= -0xff;
} else if ( (voloptions & VOL_OPTION_IS_PIPE) || !creatmode) { } else if ( (voloptions & VOL_OPTION_IS_PIPE) || !(creatmode&3) ) {
/* must exist, but don't */ /* must exist, but don't */
completition=-0xff; completition=-0xff;
} else { } else {
@ -326,7 +332,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
} }
} else { } else {
/* <========= this is NOT a PIPE Volume ====================> */ /* <========= this is NOT a PIPE Volume ====================> */
if (creatmode) { /* creat File */ if (creatmode&0x3) { /* creat File */
if (creatmode & 0x2) { /* creatnew */ if (creatmode & 0x2) { /* creatnew */
XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->fname, fhandle)); XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->fname, fhandle));
fh->fd = creat(fh->fname, 0777); fh->fd = creat(fh->fname, 0777);
@ -369,6 +375,15 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
stbuff->st_atime = stbuff->st_mtime; stbuff->st_atime = stbuff->st_mtime;
} }
fh->fd = open(fh->fname, acm); fh->fd = open(fh->fname, acm);
if (fh->fd < 0 && (creatmode&8)) {
if (did_grpchange) {
xsetegid(act_gid);
did_grpchange=0;
}
seteuid(0);
fh->fd = open(fh->fname, acm);
reset_guid();
}
XDPRINTF((5,0, "OPEN FILE:fd=%d, attrib:0x%x, access:0x%x, fh->fname:%s:fhandle=%d", XDPRINTF((5,0, "OPEN FILE:fd=%d, attrib:0x%x, access:0x%x, fh->fname:%s:fhandle=%d",
fh->fd, attrib, access, fh->fname, fhandle)); fh->fd, attrib, access, fh->fname, fhandle));
if (fh->fd < 0) if (fh->fd < 0)
@ -601,7 +616,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite)
act_connection, act_pid); act_connection, act_pid);
fh->f = ext_popen(pipecommand, geteuid(), getegid()); fh->f = ext_popen(pipecommand, geteuid(), getegid());
} }
fh->fd = (fh->f) ? fileno(fh->f->fildes[dowrite ? 0 : 1]) : -3; fh->fd = (fh->f) ? fh->f->fds[dowrite ? 0 : 1] : -3;
} }
int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
@ -613,6 +628,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->fd > -1) { if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
int readsize=size; int readsize=size;
#if 1
if (-1 == (size = read(fh->fd, data, readsize)) ) { if (-1 == (size = read(fh->fd, data, readsize)) ) {
int k=2; int k=2;
do { do {
@ -620,10 +636,24 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
} while(k-- && -1 == (size = read(fh->fd, data, readsize))); } while(k-- && -1 == (size = read(fh->fd, data, readsize)));
if (size == -1) size=0; if (size == -1) size=0;
} }
#else
int offset=0;
int k=2;
while ((size = read(fh->fd, data+offset, readsize)) < readsize) {
if (size>0) {
readsize-=size;
offset+=size;
} else if (!k-- || ((!size)&&readsize)) break;
else sleep(1);
}
size=offset;
#endif
#if 1
if (!size) { if (!size) {
if (fh->f->flags & 1) return(-0x57); if (fh->f->flags & 1) return(-0x57);
fh->f->flags |= 1; fh->f->flags |= 1;
} }
#endif
} else if (use_mmap && fh->p_mmap) { } else if (use_mmap && fh->p_mmap) {
while (1) { while (1) {
if (offset < fh->size_mmap) { if (offset < fh->size_mmap) {
@ -641,7 +671,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
} }
} /* while */ } /* while */
} else { } else {
if (use_ipx_io || fh->offd != (long)offset) { if (fh->offd != (long)offset) {
fh->offd=lseek(fh->fd, offset, SEEK_SET); fh->offd=lseek(fh->fd, offset, SEEK_SET);
if (fh->offd < 0) { if (fh->offd < 0) {
XDPRINTF((5,0,"read-file failed in lseek")); XDPRINTF((5,0,"read-file failed in lseek"));
@ -650,10 +680,6 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->offd > -1L) { if (fh->offd > -1L) {
if ((size = read(fh->fd, data, size)) > -1) { if ((size = read(fh->fd, data, size)) > -1) {
fh->offd+=(long)size; fh->offd+=(long)size;
if (use_ipx_io) {
ipx_io.fh_r=fhandle+1;
ipx_io.fd_r=fh->fd;
}
} else { } else {
XDPRINTF((5,0,"read-file failed in read")); XDPRINTF((5,0,"read-file failed in read"));
} }
@ -699,16 +725,12 @@ int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
return(size ? write(fh->fd, data, size) : 0); return(size ? write(fh->fd, data, size) : 0);
} else { } else {
if (use_ipx_io || fh->offd != (long)offset) if (fh->offd != (long)offset)
fh->offd = lseek(fh->fd, offset, SEEK_SET); fh->offd = lseek(fh->fd, offset, SEEK_SET);
if (size) { if (size) {
if (fh->offd > -1L) { if (fh->offd > -1L) {
size = write(fh->fd, data, size); size = write(fh->fd, data, size);
fh->offd+=(long)size; fh->offd+=(long)size;
if (use_ipx_io&&size>0) {
ipx_io.fh_w=fhandle+1;
ipx_io.fd_w=fh->fd;
}
} else size = -1; } else size = -1;
return(size); return(size);
} else { /* truncate FILE */ } else { /* truncate FILE */

View File

@ -1,7 +1,7 @@
/* nwfile.h 21-Jul-97 */ /* nwfile.h 21-Jul-97 */
#ifndef _NWFILE_H_ #ifndef _NWFILE_H_
#define _NWFILE_H_ #define _NWFILE_H_
#include "nwqueue.h" #include "extpipe.h"
typedef struct { typedef struct {
int task; /* for which task */ int task; /* for which task */

317
nwqconn.c Normal file
View File

@ -0,0 +1,317 @@
/* nwqconn.c 26-Aug-97 */
/* (C)opyright (C) 1997 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 <dirent.h>
#include "nwvolume.h"
#include "nwfile.h"
#include "connect.h"
#include "nwqconn.h"
typedef struct S_INT_QUEUE_JOB {
uint32 queue_id;
int job_id;
int fhandle;
struct S_INT_QUEUE_JOB *next;
} INT_QUEUE_JOB;
INT_QUEUE_JOB *queue_jobs=NULL;
static INT_QUEUE_JOB *new_queue_job(uint32 queue_id, int job_id)
{
INT_QUEUE_JOB *p=(INT_QUEUE_JOB*)xcmalloc(sizeof(INT_QUEUE_JOB));
if (!queue_jobs) {
queue_jobs=p;
} else {
INT_QUEUE_JOB *qj=queue_jobs;
while (qj->next != NULL) qj=qj->next;
qj->next=p;
}
p->next=NULL;
p->queue_id=queue_id;
p->job_id=job_id;
return(p);
}
static void free_queue_job(uint32 queue_id, int job_id)
{
INT_QUEUE_JOB *qj=queue_jobs;
if (!qj) return;
if (qj->queue_id==queue_id && qj->job_id == job_id){
queue_jobs=qj->next;
xfree(qj);
return;
}
while (qj->next) {
if (qj->next->queue_id == queue_id && qj->next->job_id == job_id) {
INT_QUEUE_JOB *tmp=qj->next;
qj->next=tmp->next;
xfree(tmp);
return;
} else qj=qj->next;
}
/* not found */
}
static INT_QUEUE_JOB *find_queue_job(uint32 queue_id, int job_id)
{
INT_QUEUE_JOB *qj=queue_jobs;
while (qj) {
if (qj->queue_id==queue_id && qj->job_id == job_id)
return(qj);
qj=qj->next;
}
return(NULL);
}
static int open_creat_queue_file(int mode, uint8
*file_name, int file_name_len,
uint8 *dirname, int dirname_len)
/* modes:
* 0 : creat
* 1 : open ro (as root)
* 2 : open rw (as root)
*/
{
int result;
result=nw_alloc_dir_handle(0, dirname, dirname_len, 99, 2, 1);
if (result > -1) {
char unixname[300];
result=conn_get_kpl_unxname(unixname, result, file_name, file_name_len);
if (result > -1) {
struct stat stbuff;
if (mode == 0) { /* creat */
result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x6, 1|4|8, 0);
if (result > -1)
chmod(unixname, 0600);
} else if (mode == 1) { /* open ro */
result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x9, 4|8, 0);
} else if (mode == 2) { /* open rw */
result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x6, 4|8, 0);
} else result=-1;
}
}
if (result < 0) {
uint8 dn[300];
uint8 fn[300];
strmaxcpy(dn, dirname, dirname_len);
strmaxcpy(fn, file_name, file_name_len);
XDPRINTF((1, 0, "open_creat_queue_file, mode=%d,result=-0x%x, dn='%s', fn='%s'",
mode, -result, dn, fn));
result=-0xff;
}
return(result);
}
int creat_queue_job(uint32 q_id,
uint8 *queue_job,
uint8 *responsedata,
uint8 old_call)
{
uint8 *dirname = (old_call) ? queue_job+sizeof(QUEUE_JOB_OLD)
: queue_job+sizeof(QUEUE_JOB);
int job_id;
INT_QUEUE_JOB *jo;
int result;
memcpy(responsedata, queue_job, (old_call) ? sizeof(QUEUE_JOB_OLD)
: sizeof(QUEUE_JOB));
if (old_call) {
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
job_id = GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id);
result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname);
if (result > -1) {
jo->fhandle = (uint32) result;
U16_TO_BE16(0, job->job_file_handle);
U32_TO_32(jo->fhandle, job->job_file_handle+2);
result = sizeof(QUEUE_JOB_OLD) - 202;
}
} else {
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
job_id=GET_BE32(job->job_id);
jo = new_queue_job(q_id, job_id);
result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname);
if (result > -1) {
jo->fhandle = (uint32) result;
U32_TO_32(jo->fhandle, job->job_file_handle);
result = sizeof(QUEUE_JOB) - 202;
}
}
if (result < 0)
free_queue_job(q_id, job_id);
return(result);
}
int close_queue_job(uint32 q_id, int job_id)
{
int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
if (jo) {
nw_close_file(jo->fhandle, 0);
result=0;
}
XDPRINTF((5,0,"close_queue_job Q=0x%x, job=%d, result=%d",
q_id, job_id, result));
return(result);
}
int close_queue_job2(uint32 q_id, int job_id,
uint8 *client_area,
uint8 *prc, int prc_len)
{
int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
XDPRINTF((5,0,"close_queue_job2, Q=0x%x, job=%d", q_id, job_id));
if (jo) {
if (prc_len) {
char unixname[300];
QUEUE_PRINT_AREA qpa;
memcpy(&qpa, client_area, sizeof(QUEUE_PRINT_AREA));
strmaxcpy((uint8*)unixname,
(uint8*)file_get_unix_name(jo->fhandle), sizeof(unixname)-1);
XDPRINTF((5,0,"nw_close_file_queue fhandle=%d", jo->fhandle));
if (*unixname) {
char buff[1024];
char printcommand[300];
FILE *f=NULL;
if (prc_len && *(prc+prc_len-1)=='!'){
strmaxcpy((uint8*)buff, prc, prc_len-1);
sprintf(printcommand, "%s %s %s", buff,
qpa.banner_user_name, qpa.banner_file_name);
} else
strmaxcpy((uint8*)printcommand, prc, prc_len);
nw_close_file(jo->fhandle, 1);
jo->fhandle = 0L;
if (NULL == (f = fopen(unixname, "r"))) {
/* OK now we try the open as root */
seteuid(0);
f = fopen(unixname, "r");
reset_guid();
}
if (NULL != f) {
int is_ok = 0;
FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid());
if (fp) {
int k;
is_ok++;
while (is_ok && (k = fread(buff, 1, sizeof(buff), f)) > 0) {
if (k != write(fp->fds[0], buff, k)) {
XDPRINTF((1,0x10,"Cannot write to pipe `%s`", printcommand));
if ((k=read(fp->fds[2], buff, sizeof(buff)-1)) > 0 ) {
buff[k]='\0';
XDPRINTF((1,0x0,"err='%s'", buff));
}
is_ok=0;
}
}
if (0 != (k=ext_pclose(fp))) {
XDPRINTF((1,0,"Errorresult = %d by closing print pipe", k));
}
}
fclose(f);
if (is_ok) {
seteuid(0);
unlink(unixname);
reset_guid();
result=0;
}
} else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname));
}
} else {
nw_close_file(jo->fhandle, 1);
}
free_queue_job(q_id, job_id);
}
return(result);
}
int service_queue_job(uint32 q_id,
uint8 *queue_job,
uint8 *responsedata,
uint8 old_call)
{
uint8 *dirname = (old_call) ? queue_job+sizeof(QUEUE_JOB_OLD)
: queue_job+sizeof(QUEUE_JOB);
int job_id;
INT_QUEUE_JOB *jo;
int result;
memcpy(responsedata, queue_job, (old_call) ? sizeof(QUEUE_JOB_OLD)
: sizeof(QUEUE_JOB));
if (old_call) {
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
job_id = GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id);
result = open_creat_queue_file(1,
job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname);
if (result > -1) {
jo->fhandle = (uint32) result;
U16_TO_BE16(0, job->job_file_handle);
U32_TO_32(jo->fhandle, job->job_file_handle+2);
result = sizeof(QUEUE_JOB_OLD) - 202;
}
} else {
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
job_id=GET_BE32(job->job_id);
jo = new_queue_job(q_id, job_id);
result = open_creat_queue_file(1,
job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname);
if (result > -1) {
jo->fhandle = (uint32) result;
U32_TO_32(jo->fhandle, job->job_file_handle);
result = sizeof(QUEUE_JOB) - 202;
}
}
if (result < 0)
free_queue_job(q_id, job_id);
return(result);
}
int finish_abort_queue_job(uint32 q_id, int job_id)
{
int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
if (jo) {
nw_close_file(jo->fhandle, 0);
free_queue_job(q_id, job_id);
result=0;
}
XDPRINTF((5,0,"finish_abort_queue_job Q=0x%x, job=%d, result=%d",
q_id, job_id, result));
return(result);
}
void free_queue_jobs(void)
{
INT_QUEUE_JOB *qj=queue_jobs;
while(qj){
INT_QUEUE_JOB *tmp=qj;
qj=qj->next;
xfree(tmp);
}
queue_jobs=NULL;
}

23
nwqconn.h Normal file
View File

@ -0,0 +1,23 @@
/* nwqconn.h 26-Aug-97 */
#ifndef _NWQCONN_H_
#define _NWQCONN_H_
#include "queuedef.h"
extern int creat_queue_job(uint32 q_id,
uint8 *queue_job,
uint8 *responsedata,
uint8 old_call);
extern int close_queue_job(uint32 q_id, int job_id);
extern int close_queue_job2(uint32 q_id, int job_id,
uint8 *client_area,
uint8 *prc, int prc_len);
extern int service_queue_job(uint32 q_id,
uint8 *queue_job,
uint8 *responsedata,
uint8 old_call);
extern int finish_abort_queue_job(uint32 q_id, int job_id);
extern void free_queue_jobs(void);
#endif

1166
nwqueue.c

File diff suppressed because it is too large Load Diff

111
nwqueue.h
View File

@ -1,93 +1,44 @@
/* nwqueue.h 04-May-96 */ /* nwqueue.h 18-Aug-97 */
#ifndef _NWQUEUE_H_ #ifndef _NWQUEUE_H_
#define _NWQUEUE_H_ #define _NWQUEUE_H_
#include "queuedef.h"
/* enhanced pipe handling */ extern int nw_get_q_dirname(uint32 q_id, uint8 *buff);
typedef struct {
FILE *fildes[3]; /* filedescriptor to 0,1,2 of new process */
int command_pid; /* pid of piped command */
int flags; /* special flags */
} FILE_PIPE;
extern int ext_pclose(FILE_PIPE *fp); extern int nw_creat_queue_job(int connection, int task, uint32 object_id,
extern FILE_PIPE *ext_popen(char *command, int uid, int gid); uint32 q_id, uint8 *q_job, uint8 *responsedata,
int old_call);
/* queues */ extern int nw_close_queue_job(uint32 q_id, int job_id,
typedef struct { uint8 *responsedata);
uint8 record_in_use[2];
uint8 record_previous[4];
uint8 record_next[4];
uint8 client_connection[4];
uint8 client_task[4];
uint8 client_id[4];
uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */ extern int nw_get_queue_status(uint32 q_id, int *status, int *entries,
uint8 target_execute_time[6]; /* all 0xff */ int *servers, int server_ids[], int server_conns[]);
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 ? */
uint8 job_control_flags[2]; /* z.B 0x10, 0x00 */
/* 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 */ extern int nw_get_q_job_entry(uint32 q_id, int job_id,
uint8 job_file_handle[4]; uint8 *responsedata, int old_call);
uint8 server_station[4]; extern int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata);
uint8 server_task[4]; extern int nw_get_queue_job_file_size(uint32 q_id, int job_id);
uint8 server_id[4];
uint8 job_bez[50]; /* "LPT1 Catch" */
uint8 client_area[152];
} QUEUE_JOB;
typedef struct { extern int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id);
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 */ /* ------------------ for queue servers ------------------- */
uint8 job_file_handle[6]; extern int nw_attach_server_to_queue(uint32 user_id,
uint8 server_station; int connection,
uint8 server_task; uint32 q_id);
uint8 server_id[4];
uint8 job_bez[50]; /* "LPT1 Catch" */
uint8 client_area[152];
} QUEUE_JOB_OLD; /* before 3.11 */
typedef struct { extern int nw_detach_server_from_queue(uint32 user_id,
uint8 version; /* normal 0x0 */ int connection,
uint8 tabsize; /* normal 0x8 */ uint32 q_id);
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]; /* all zero */
uint8 banner_user_name[13]; /* "SUPERVISOR" */
uint8 banner_file_name[13]; /* "LST:" */
uint8 banner_header_file_name[14]; /* all zero */
uint8 file_path_name[80]; /* all zero */
} QUEUE_PRINT_AREA;
extern int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job, extern int nw_service_queue_job(uint32 user_id, int connection, int task,
uint8 *dirname, int dir_nam_len, int old_call); uint32 q_id, int job_typ,
uint8 *responsedata, int old_call);
extern int nw_close_file_queue(uint8 *queue_id, extern int nw_finish_abort_queue_job(int mode, uint32 user_id, int connection,
uint8 *job_id, uint32 q_id, int job_id);
uint8 *prc, int prc_len);
extern void exit_queues(void);
extern void init_queues(uint8 *unixname, int unixname_len,
int downshift, uint8 *sysname);
#endif #endif

View File

@ -1,4 +1,4 @@
/* nwvolume.c 20-Jul-97 */ /* nwvolume.c 02-Aug-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -34,6 +34,7 @@
NW_VOL *nw_volumes=NULL; NW_VOL *nw_volumes=NULL;
int used_nw_volumes=0; int used_nw_volumes=0;
int loaded_namespaces=0;
uint8 *home_dir=NULL; uint8 *home_dir=NULL;
int home_dir_len=0; int home_dir_len=0;
char *path_vol_inodes_cache=NULL; char *path_vol_inodes_cache=NULL;
@ -78,7 +79,8 @@ void nw_init_volumes(FILE *f)
} }
} }
rewind(f); rewind(f);
used_nw_volumes = 0; used_nw_volumes = 0;
loaded_namespaces = 0;
new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache"); new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache");
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){ if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){
@ -91,6 +93,7 @@ void nw_init_volumes(FILE *f)
if (founds > 1) { if (founds > 1) {
NW_VOL *vol=&(nw_volumes[used_nw_volumes]); NW_VOL *vol=&(nw_volumes[used_nw_volumes]);
vol->options = VOL_NAMESPACE_DOS; vol->options = VOL_NAMESPACE_DOS;
loaded_namespaces |= VOL_NAMESPACE_DOS;
up_fn(sysname); up_fn(sysname);
new_str(vol->sysname, sysname); new_str(vol->sysname, sysname);
if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') { if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') {
@ -133,10 +136,12 @@ void nw_init_volumes(FILE *f)
case 'O' : vol->options case 'O' : vol->options
|= VOL_NAMESPACE_OS2; |= VOL_NAMESPACE_OS2;
loaded_namespaces |= VOL_NAMESPACE_OS2;
break; break;
case 'N' : vol->options case 'N' : vol->options
|= VOL_NAMESPACE_NFS; |= VOL_NAMESPACE_NFS;
loaded_namespaces |= VOL_NAMESPACE_NFS;
break; break;
default : break; default : break;

View File

@ -1,4 +1,4 @@
/* nwvolume.h 20-Jul-97 */ /* nwvolume.h 02-Aug-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -69,6 +69,7 @@ struct fs_usage {
extern NW_VOL *nw_volumes; extern NW_VOL *nw_volumes;
extern int used_nw_volumes; extern int used_nw_volumes;
extern int loaded_namespaces;
extern uint8 *home_dir; extern uint8 *home_dir;
extern int home_dir_len; extern int home_dir_len;
extern char *path_vol_inodes_cache; /* for namespace routines */ extern char *path_vol_inodes_cache; /* for namespace routines */

78
queuedef.h Normal file
View File

@ -0,0 +1,78 @@
/* queuedef.h 09-Aug-97 */
#ifndef _QUEUEDEF_H_
#define _QUEUEDEF_H_
typedef struct {
uint8 record_in_use[2];
uint8 record_previous[4];
uint8 record_next[4];
uint8 client_connection[4]; /* Lo-Hi */
uint8 client_task[4]; /* Lo-Hi */
uint8 client_id[4]; /* Hi-Lo */
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[4]; /* Hi-Lo */
uint8 job_typ[2]; /* Hi-Lo */
uint8 job_position[2]; /* Lo-Hi, e.g. 0x01, 0x00 */
uint8 job_control_flags[2]; /* Lo-Hi, e.g. 0x10, 0x00 */
/* 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[4];
uint8 server_station[4];
uint8 server_task[4];
uint8 server_id[4];
/* offset 78 */
uint8 job_description[50]; /* "LPT1 Catch" */
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]; /* Hi-Lo */
uint8 job_typ[2]; /* Hi-Lo */
uint8 job_position; /* zero */
uint8 job_control_flags;
/* 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];
/* offset 54 */
uint8 job_description[50]; /* "LPT1 Catch" */
uint8 client_area[152];
} QUEUE_JOB_OLD; /* before 3.11 */
typedef struct {
uint8 version; /* normal 0x0 */
uint8 tabsize; /* normal 0x8 */
uint8 count_copies[2]; /* copies 0x0, 0x01 */
uint8 print_flags[2]; /* 0x0, 0xc0 e.g. with banner */
uint8 max_lines[2]; /* 0x0, 0x42 */
uint8 max_chars[2]; /* 0x0, 0x84 */
uint8 form_name[16]; /* "UNKNOWN" */
uint8 reserved[6]; /* all zero */
uint8 banner_user_name[13]; /* "SUPERVISOR" */
uint8 banner_file_name[13]; /* "LST:" */
uint8 banner_header_file_name[14]; /* all zero */
uint8 file_path_name[80]; /* all zero */
} QUEUE_PRINT_AREA;
#endif

259
sema.c Normal file
View File

@ -0,0 +1,259 @@
/* sema.c :07-Aug-97 */
/* simple semaphore emulation, needs more work */
/* (C)opyright (C) 1997 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 "nwbind.h"
#include "sema.h"
#define MAX_SEMAPHORES 100
typedef struct {
int namlen;
uint8 *name;
int opencount;
int value;
} SEMA;
static int count_semas=0;
static SEMA *semas[MAX_SEMAPHORES];
static int open_sema(int namlen, uint8 *name, int value, int *opencount)
{
int k=-1;
int isfree=-1;
SEMA *se;
while (++k < count_semas){
se=semas[k];
if (se) {
if (se->namlen==namlen && !memcmp(se->name, name, namlen)) {
*opencount=++(se->opencount);
return(++k);
}
} else if (isfree<0) isfree=k;
}
if (isfree<0 && count_semas < MAX_SEMAPHORES)
isfree=count_semas++;
if (isfree < 0) return(-0x96); /* out of mem */
se=semas[isfree]=(SEMA*)xcmalloc(sizeof(SEMA));
se->namlen=namlen;
se->name=xmalloc(namlen);
memcpy(se->name, name, namlen);
se->value=value;
*opencount=se->opencount=1;
return(++isfree);
}
static int close_sema(int handle)
{
SEMA *se;
if (handle > 0 && --handle < count_semas && NULL != (se=semas[handle])){
if (!(--se->opencount)) {
xfree(se->name);
xfree(se);
semas[handle]=NULL;
while (handle == count_semas-1) {
--count_semas;
if (!handle || semas[--handle]) break;
}
}
return(0);
}
return(-0xff); /* wrong handle */
}
static int wait_sema(int handle, int timeout)
{
SEMA *se;
if (handle > 0 && --handle < count_semas && NULL != (se=semas[handle])){
if (se->value < 1) return(-0xfe); /* timeout */
--se->value;
return(0);
}
return(-0xff); /* wrong handle */
}
static int signal_sema(int handle)
{
SEMA *se;
if (handle > 0 && --handle < count_semas && NULL != (se=semas[handle])){
++se->value;
return(0);
}
return(-0xff); /* wrong handle */
}
static int examine_sema(int handle, int *value, int *opencount)
{
SEMA *se;
if (handle > 0 && --handle < count_semas && NULL != (se=semas[handle])){
*value=se->value;
*opencount=se->opencount;
return(0);
}
return(-0xff); /* wrong handle */
}
static int open_conn_sema(CONNECTION *c, int handle)
{
int k=c->count_semas;
int is_free=-1;
SEMA_CONN *sem;
while (k--) {
sem=&(c->semas[k]);
if (sem->handle==handle) {
sem->opencount++;
return(handle);
} else if (!sem->handle) is_free=k;
}
if (is_free < 0 && c->count_semas < MAX_SEMA_CONN)
is_free=c->count_semas++;
if (is_free < 0)
return(-0x96); /* we say out of mem here */
sem=&(c->semas[is_free]);
sem->handle=handle;
sem->opencount=1;
return(handle);
}
static int close_conn_sema(CONNECTION *c, int handle)
{
int k=c->count_semas;
SEMA_CONN *sem;
while (k--) {
sem=&(c->semas[k]);
if (sem->handle==handle) {
if (!--sem->opencount) {
sem->handle=0;
if (k==c->count_semas-1) {
while(c->count_semas > 0
&& !(c->semas[c->count_semas-1].handle) )
--c->count_semas;
}
}
return(0);
}
}
return(-0xff); /* wrong handle */
}
void clear_conn_semas(CONNECTION *c)
/* removes semas which are opened by this connection */
{
while (c->count_semas--) {
SEMA_CONN *sem=&(c->semas[c->count_semas]);
if (sem->handle>0&&sem->opencount>0) {
while (sem->opencount--)
close_sema(sem->handle);
}
}
c->count_semas=0;
}
int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
{
int result = -0xfb; /* unknown request */
XDPRINTF((3, 0, "0x20 call ufunc=0x%x", ufunc));
switch (ufunc) {
case 0x0 : { /* open semaphore */
int value = *p;
int namlen = *(p+1);
uint8 *name = (p+2);
struct XDATA {
uint8 handle[4];
uint8 opencount;
} *xdata = (struct XDATA*) responsedata;
int opencount;
if (namlen < 1 || namlen > 127) return(-0xfe);
if (value > 127) return(-0xff);
result=open_sema(namlen, name, value, &opencount);
if (result > -1) {
result=open_conn_sema(c, result);
if (result < 0){
close_sema(result);
}
}
if (nw_debug>1){
name[namlen]=0;
XDPRINTF((2, 0, "open_sem:`%s` value=%d, count=%d, handle=%d",
name, value, opencount, result));
}
if (result > -1) {
U32_TO_BE32(result, xdata->handle);
xdata->opencount=(uint8)opencount;
result=sizeof(*xdata);
}
}
break;
case 0x1 : { /* examine semaphore */
int handle = GET_BE32(p);
struct XDATA {
char value;
uint8 opencount;
} *xdata = (struct XDATA*) responsedata;
int value;
int opencount;
result=examine_sema(handle, &value, &opencount);
XDPRINTF((2, 0, "examine_sem:%d, value=%d, opcount=%d, result=%d",
handle, value, opencount, result));
if (result > -1) {
xdata->value=(char)value;
xdata->opencount=(uint8)opencount;
result=sizeof(*xdata);
}
}
break;
case 0x2 : { /* wait on semaphore */
int handle = GET_BE32(p);
int timeout = GET_BE16(p+4);
result=wait_sema(handle, timeout);
XDPRINTF((2, 0, "wait_sem:%d, timeout=%d, result=%d",
handle, timeout, result));
}
break;
case 0x3 : { /* signal sema */
int handle = GET_BE32(p);
result=signal_sema(handle);
XDPRINTF((2, 0, "signal_sem:%d, result=%d",
handle, result));
}
break;
case 0x4 : { /* close semaphore */
int handle = GET_BE32(p);
result=close_conn_sema(c, handle);
if (!result)
result=close_sema(handle);
XDPRINTF((2, 0, "close_sem:%d, result=%d",
handle, result));
}
break;
default : break;
}
return(result);
}

9
sema.h Normal file
View File

@ -0,0 +1,9 @@
/* sema.h: 07-Aug-97 */
#ifndef _SEMA_H_
#define _SEMA_H_
extern void clear_conn_semas(CONNECTION *c);
extern int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata);
#endif

53
tools.c
View File

@ -115,12 +115,14 @@ static char *buffered=NULL;
int errnum = errno; int errnum = errno;
if (nw_debug >= dlevel) { if (nw_debug >= dlevel) {
if (use_syslog==1) { if (use_syslog==1) {
char buf[2048]; /* should be ever big enough */ char *buf;
char *pb=buf; char *pb;
if (buffered) { if (buffered) {
strcpy(buf, buffered); buf=buffered;
xfree(buffered); pb=buf+strlen(buffered);
pb+=strlen(buf); buffered=NULL;
} else {
pb=buf=xmalloc(2048);
} }
if (p) { if (p) {
int l; int l;
@ -143,9 +145,10 @@ static char *buffered=NULL;
closelog(); closelog();
} else { } else {
int l=strlen(buf); int l=strlen(buf);
buffered=xmalloc(l+1); buffered=xmalloc(l+2048);
strcpy(buffered, buf); memcpy(buffered, buf, l+1);
} }
xfree(buf);
} else { } else {
if (!(mode & 1)) if (!(mode & 1))
fprintf(logfile, "%-8s %d:", get_modstr(), connection); fprintf(logfile, "%-8s %d:", get_modstr(), connection);
@ -288,6 +291,7 @@ int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize)
} }
static uint8 *path_bindery=NULL; static uint8 *path_bindery=NULL;
static uint8 *path_spool=NULL;
char *get_div_pathes(char *buff, char *name, int what, char *p, ... ) char *get_div_pathes(char *buff, char *name, int what, char *p, ... )
{ {
@ -297,15 +301,29 @@ char *get_div_pathes(char *buff, char *name, int what, char *p, ... )
switch (what) { switch (what) {
case 0 : wpath = PATHNAME_PROGS; break; case 0 : wpath = PATHNAME_PROGS; break;
case 1 : if (path_bindery==NULL) { case 1 : if (path_bindery==NULL) {
if (get_ini_entry(NULL, 45, locbuf, sizeof(locbuf)) if (get_ini_entry(NULL, 45, locbuf, sizeof(locbuf))
&& *locbuf) { && *locbuf) {
new_str(path_bindery, locbuf); new_str(path_bindery, locbuf);
} else } else
new_str(path_bindery, PATHNAME_BINDERY); new_str(path_bindery, PATHNAME_BINDERY);
} }
wpath = path_bindery; wpath = path_bindery;
break; break;
case 2 : wpath = PATHNAME_PIDFILES; break; case 2 : wpath = PATHNAME_PIDFILES; break;
case 3 :
case 4 : if (path_spool==NULL) {
if (get_ini_entry(NULL, 42, locbuf, sizeof(locbuf))
&& *locbuf) {
new_str(path_spool, locbuf);
} else
new_str(path_spool, "/var/spool/nwserv");
}
wpath = path_spool;
if (what==4) name="queues/";
break;
default : buff[0]='\0'; default : buff[0]='\0';
return(buff); return(buff);
} }
@ -375,7 +393,7 @@ void get_debug_level(uint8 *buf)
char dummy; char dummy;
if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1) if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1)
sscanf(buf2, "%lx", &debug_mask); sscanf(buf2, "%lx", &debug_mask);
} }
} }
} }
@ -390,7 +408,7 @@ void get_ini_debug(int module)
*/ */
{ {
uint8 buff[300]; uint8 buff[300];
if (get_ini_entry(NULL, 100+module, buff, sizeof(buff))) if (get_ini_entry(NULL, 100+module, buff, sizeof(buff)))
get_debug_level(buff); get_debug_level(buff);
} }
@ -466,6 +484,19 @@ void init_tools(int module, int options)
if (!strcmp(logfilename, "syslog")) if (!strcmp(logfilename, "syslog"))
use_syslog=1; use_syslog=1;
if (NWSERV == module) {
fprintf(stdout, "\n\nMars_nwe V%d.%02dpl%d started using %s.\n",
_VERS_H_, _VERS_L_, _VERS_P_, FILENAME_NW_INI);
fprintf(stdout, "If you have problems, please read mars_nwe/doc/BUGS !\n");
if (use_syslog==1) {
fprintf(stdout, "Errors/warnings will be reported in syslog\n");
} else {
fprintf(stdout, "Errors/warnings will be reported in %s\n", logfilename);
}
fprintf(stdout, "\n\n");
fflush(stdout);
}
if (NWSERV == module || NWROUTED == module) { /* now make daemon */ if (NWSERV == module || NWROUTED == module) { /* now make daemon */
int fd=fork(); int fd=fork();
if (fd) exit((fd > 0) ? 0 : 1); if (fd) exit((fd > 0) ? 0 : 1);