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_SEARCH 0x10 /* file search */
/* NWBIND */
#define D_BIND_REQ 0x8000 /* all Requests */
#endif

View File

@ -10,6 +10,7 @@ If you have problems.
Section 1: volumes
Section 3: Number of the internal network
Section 4: IPX-devices
Section 5: device flags
Section 6: version-"spoofing"
Section 12: supervisor-login
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.
---------------------------------------------
- report your running environment
full mars_nwe version, example: 0.98.pl5
linux-kernel, 2.0.23
full mars_nwe version, example: 0.99.pl0
linux-kernel, 2.0.29
exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. )
changes you made into nwserv.conf(nw.ini), config.h.
- if you send nwserv.conf, please remove the comments first.

View File

@ -1,6 +1,6 @@
Sorry, this is in German only.
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
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -349,3 +349,14 @@ Erste 'oeffentliche' Version
- Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.)
korrigiert.
<----- ^^^^^^^^^^ 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>
testings, wrote syslog stuff
Peter Beno <Peter.Beno@anasoft.ana.sk>
testings+bugfixes
Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
testing router code on token ring
wrote the 'crypted change password' routines !
@ -46,6 +49,9 @@ Volker Lendecke <lendecke@math.uni-goettingen.de>
Ambrose Li <acli@acli.interlog.com>
gave hints, patches, docs
Andreas Liebmann <Liebmann@bbs1.btf.st.schule.de>
docs
James B. MacLean <macleajb@ednet.ns.ca>
many testings+notes

View File

@ -49,6 +49,10 @@ A: Give the volume the 'O' flag.
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR]
"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)
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

View File

@ -4,7 +4,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
die IPX-Interfaces per ini/conf Datei konfigurieren
und als RIP/SAP Router arbeiten.
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.
In diesem Modus wurde das korrekte Zusammenspiel mit
dosemu, ncpfs oder Caldera's nwclient getestet.
@ -21,7 +21,7 @@ Mars_nwe kann auf 2 Arten konfiguriert werden.
Netwerknummer erhalten.
Es muss ein Eintrag '4' mit Netzwerk Nummer = 0,
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)
3 0x0 # verwende IP Nummer als Internal Net.
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.
Routing usw. soll von anderen Programmen erledigt werden.
-> Die IPX-Interfaces muessen durch andere Programme/Tools
wie 'ipx-configure' oder aehnliche eingerichtet werden
und es muss ein rip/sap router/daemon eingerichtet sein.
wie 'ipx-interface, ipx-configure' oder aehnliche eingerichtet
werden und es muss ein rip/sap router/daemon eingerichtet sein.
In mars_nwe/config.h muss folgende Zeile vorhanden sein.
#define INTERNAL_RIP_SAP 0
@ -72,5 +72,46 @@ sind.
Falls nwserv nicht daemonisiert wurde, kann der Server mit ^C
wieder gestoppt werden, ansonsten muss nwserv per Dos Client
(fconsole server down) gestoppt werden (Supervisor) oder per
'kill' Befehl. Je nach Eintrag 210 in der nw.ini Datei kann
'nwserv -k' Befehl. Je nach Eintrag 210 in der nw.ini Datei kann
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 ---------
- Client-32 from Novell should now work. (added vol/dev/inode/path cache)
The cache directory '/var/spool/nwserv/.volcache' should/can be controlled

View File

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

View File

@ -2,12 +2,14 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux.
#
# last changed: 20-Jul-97
# last changed: 30-Aug-97
#
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
#
# since version 0.98.pl11:
# the most important options in config.h can now be altered in
# this file begin at section 60.
#
# This file specifies which Linux-resources (printers, users, directories)
@ -68,6 +70,31 @@
# volume; use the special name "~" to refer to the users
# 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)
#
# 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
# 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'.
# -------------------------------------------------------------------------
# Syntax:
@ -561,31 +588,50 @@
#
# -------------------------------------------------------------------------
# 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
# perfectly clear: _not_ the Linux-queue)
# QUEUE_DIR: spooling directory for the print-jobs.
# The name is the DOS (not Unix) name of this
# directory.
# It should be placed on the first defined volume.
# It must be placed on the first defined volume.
# (standard name is SYS volume).
# Then it will be created at starttime of mars_nwe.
# It must exist before printing.
# (_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
# (see "man lpr" and "man magicfilter" for details)
# if the '!' is last parameter of command then
# the queue-packet fields 'banner_user_name'
# and 'banner_file_name' will be added to the
# 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:
# 21 LASER SYS:/PRINT/L lpr -Plaser
# 21 OCTOPUSS SYS:/PRINT/O lpr -Php_deskjet
# 21 LASER - lpr -Plaser
# 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)
#
@ -605,10 +651,12 @@
40 /var/spool/nwserv/.volcache
# 41 = path for share/lock files
41 /var/spool/nwserv/.locks
# 42 = path for spool dir
42 /var/spool/nwserv
#
#
# 45 = path for bindery file's
45 /etc
# =========================================================================
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
# 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
#makefile.unx 09-Jul-97
#makefile.unx 09-Aug-97
#endif
VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0
V_L=99
P_L=0
P_L=1
#define D_P_L 1
DISTRIB=mars_nwe
@ -113,24 +113,26 @@ PROGS=$(INSTALLPROGS) $(PROG8)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_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)
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)
OBJ8= $(OBJ6)
OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
$(EMUTLIOBJ1) $(NWROUTE_O) \
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\
nwqueue$(O) nameos2$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) \
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \
$(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \
$(PROG7)$(O) $(PROG8)$(O)
HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \
unxfile$(O)
HOBJ6= $(PROG6)$(O) sema$(O)
#if 0
#$(PROG1): $(PROG1)$(O) $(OBJ1)
# $(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)
$(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h
$(HOBJ6): nwbind.h sema.h
$(OBJS): net.h config.h
$(PROG7)$(O): nwserv.c nwroute.c
tools$(O): $(DESTMAKEFILE)

View File

@ -249,7 +249,7 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
continue;
default : if (soptions & VOL_OPTION_IGNCASE) {
if (!dfn_imatch(*s, *p))
if (!dfn_imatch(*s, pc))
return(0);
} else if (pc != *s) return(0);
++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 !!!!!!!!!! */
/* 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);
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) {
U32_TO_32(stb->st_size, p);
}
p += 4;
if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
uint32 attrib = (voloptions & VOL_OPTION_IS_PIPE)
? (uint32) FILE_ATTR_SHARE
: (uint32) un_nw_attrib(stb, 0, 0);
uint32 attrib = ( (!S_ISDIR(stb->st_mode))
&& (voloptions & VOL_OPTION_IS_PIPE) )
? (uint32) FILE_ATTR_SHARE|FILE_ATTR_A
: (uint32) un_nw_attrib(stb, 0, 0);
U32_TO_32(attrib, p);
p += 4;
U16_TO_16((uint16)(attrib & 0xFFFF), p);
@ -1517,7 +1526,8 @@ static int nw_open_creat_file_or_dir(
int exist = result;
uint8 last_part[258];
*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);
XDPRINTF((5, 0, "nw_open_c... result=%d, last_part='%s'",
result, last_part));
@ -1533,7 +1543,7 @@ static int nw_open_creat_file_or_dir(
if (!(creatattrib & FILE_ATTR_DIR)) {
int creatmode=0; /* open */
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 0
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),
attrib, access_rights, creatmode, task)) > -1) {
fhandle = (uint32) result;
#if 0
#if 1 /* should be ok, 31-Jul-97 0.99.pl1 */
actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */
#endif
if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE))
@ -1572,32 +1582,136 @@ static int nw_open_creat_file_or_dir(
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,
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) {
DIR_BASE_ENTRY *dbe=dir_base[result];
uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2);
if (get_volume_options(dbe->nwpath.volume) &
VOL_OPTION_READONLY) result = -0x8a;
else {
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);
}
}
VOL_OPTION_READONLY) result = -0x8a;
else result=func_search_entry(dbe, namespace,
search_entry, strlen(search_entry), searchattrib,
delete_file_dir, NULL);
}
return(result);
}
@ -1674,6 +1788,8 @@ static int nw_get_full_path_cookies(int namespace,
*(p++) = (uint8)l;
memcpy(p, pp, l);
*(p+l)='\0';
if (!namespace)
up_fn(p);
k++;
XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p));
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 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
*
@ -108,6 +108,7 @@ typedef struct {
extern int handle_func_0x57(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,
int namspace, uint8 *rdata);

355
nwbind.c
View File

@ -1,5 +1,5 @@
/* nwbind.c */
#define REVISION_DATE "22-Jul-97"
#define REVISION_DATE "26-Aug-97"
/* NCP Bindery SUB-SERVER */
/* authentification and some message handling */
@ -22,6 +22,9 @@
#include "net.h"
#include "nwdbm.h"
#include "unxlog.h"
#include "nwbind.h"
#include "nwqueue.h"
#include "sema.h"
/* next should be '1', is for testing only */
#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() \
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_connections=MAX_CONNECTIONS;
@ -163,13 +155,17 @@ static void open_clear_connection(int conn, int activate, uint8 *addr)
c->active = activate;
c->message[0] = '\0';
c->t_login = 0;
if (activate && addr) {
memcpy(&(c->client_adr), 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));
} else {
} else { /* down connection */
if (c->object_id)
write_utmp(0, conn+1, c->pid_nwconn, &(c->client_adr), NULL);
if (c->count_semas) {
clear_conn_semas(c);
}
}
c->object_id = 0;
}
@ -221,29 +217,38 @@ static void handle_fxx(int gelen, int func)
uint8 len = *(requestdata+1);
#endif
uint8 ufunc = *(requestdata+2);
uint8 *rdata = requestdata+3;
uint8 ufunc;
uint8 *rdata;
uint8 completition = 0;
uint8 connect_status= 0;
int data_len = 0;
if (nw_debug > 1){
int j = gelen - sizeof(NCPREQUEST);
if (nw_debug){
if (func == 0x19) ufunc=0;
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 (func==0x19) {
ufunc = 0;
rdata = requestdata;
} else if (func==0x20) {
ufunc = *requestdata;
rdata = requestdata+1;
} else {
ufunc = *(requestdata+2);
rdata = requestdata+3;
}
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) {
switch (ufunc) { /* Messages */
case 0x0 : { /* Send Broadcast Message (old) */
@ -307,11 +312,13 @@ static void handle_fxx(int gelen, int func)
case 0x29 : { /* Read volume restrictions */
/* Returns 3 integers, uid, gid, 0=OK/1=Permission denied */
uint32 id = GET_BE32(rdata+1);
internal_act=1;
if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)),
id, (char *) NULL) != 0) {
completition = 0xff;
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 */
if (act_c->object_id == 1 ||
(act_c->object_id == id && ufunc == 0x29))
@ -446,16 +453,20 @@ static void handle_fxx(int gelen, int func)
? (int) *rdata
: act_connection)
: GET_32(rdata);
if (conn && --conn < max_connections
&& connections[conn].active ) {
CONNECTION *cx=&(connections[conn]);
if (conn >0 && conn <= max_connections
&& connections[conn-1].active ) {
CONNECTION *cx=&(connections[conn-1]);
data_len = sizeof(ipxAddr_t);
memcpy(responsedata, (char*)&(cx->client_adr), data_len);
if (ufunc==0x1a) {
*(responsedata+data_len)=0x02; /* NCP connection */
data_len++;
}
} else completition = 0xff;
} else {
XDPRINTF((1, 0, "Get Connection Internet Adress, Conn:%d of %d failed",
conn, max_connections));
completition = 0xff;
}
} break;
case 0x14 : { /* Login Objekt, unencrypted passwords */
@ -1087,94 +1098,178 @@ static void handle_fxx(int gelen, int func)
completition=0xfb;
} break;
case 0x66 : { /* Read Queue Current Status,old */
/* !!!!!! TO DO */
NETOBJ obj;
case 0x66 : { /* Read Queue Current Status,old */
struct XDATA {
uint8 queue_id[4];
uint8 id[4];
uint8 status;
uint8 entries;
uint8 servers;
uint8 data[1]; /* server_id + server_station list */
uint8 data[1];
} *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata);
memset(xdata, 0, sizeof(struct XDATA));
U32_TO_BE32(obj.id, xdata->queue_id);
data_len = sizeof(struct XDATA);
XDPRINTF((1, 0, "TODO:READ QUEUE STATUS,old of Q=0x%lx", obj.id));
uint32 q_id = GET_BE32(rdata);
int status;
int entries;
int servers;
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;
case 0x6A : /* Remove Job from Queue OLD */
case 0x80 : { /* Remove Job from Queue NEW */
NETOBJ obj;
uint32 jobnr = (ufunc == 0x6A)
uint32 q_id = GET_BE32(rdata);
uint32 job_id = (ufunc == 0x6A)
? GET_BE16(rdata+4)
: GET_BE32(rdata+4);
obj.id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO:Remove Job=%ld from Queue Q=0x%lx", jobnr, obj.id));
completition=0xd5; /* no Queue Job */
}break;
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
int result=nw_remove_job_from_queue(
act_c->object_id,
q_id, job_id);
if (result < 0)
completition=(uint8)-result;
}
break;
case 0x6C : { /* Get Queue Job Entry */
/* !!!!!! TODO */
NETOBJ obj;
obj.id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO: GET QUEUE JOB ENTRY of Q=0x%lx", obj.id));
case 0x6B : { /* Get Queue Job List, old */
uint32 q_id=GET_BE32(rdata);
int result=nw_get_queue_job_list_old(q_id, responsedata);
if (result > -1)
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;
case 0x68: /* creat queue job and file old */
case 0x79: { /* creat queue job and file new */
uint32 q_id = GET_BE32(rdata);
uint8 *dir_name = responsedata+1;
int result = nw_get_q_dirname(q_id, dir_name);
if (result > -1) {
*(dir_name-1) = result;
data_len = result+1;
} else {
/*
static int re=0x96;
*/
completition = (uint8) 0xd3; /* err no queue rights */
/*
if (re == 0x96) re=0xd0;
else if (re < 0xff) ++re;
*/
}
uint32 q_id = GET_BE32(rdata);
uint8 *q_job = rdata+4; /* jobsize = 256(old) or 280 */
int result = nw_creat_queue_job(
act_connection, ncprequest->task,
act_c->object_id,
q_id, q_job,
responsedata,
ufunc==0x68);
if (result > -1)
data_len=result;
else
completition = (uint8) -result;
/*0xd3 err no queue rights */
}
break;
case 0x69: /* close file and start queue old ?? */
case 0x7f: { /* close file and start queue */
uint32 q_id = GET_BE32(rdata);
uint8 *prc = responsedata+1;
int result = nw_get_q_prcommand(q_id, prc);
if (result > -1) {
*(prc-1) = result;
data_len = result+1;
} else completition = (uint8) 0xff;
uint32 job_id = (ufunc==0x69)
? GET_BE16(rdata+4)
: GET_BE32(rdata+4);
int result = nw_close_queue_job(q_id, job_id,
responsedata);
if (result > -1)
data_len=result;
else
completition = (uint8) -result;
}
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 */
NETOBJ obj;
struct XDATA {
uint8 id[4]; /* queue id */
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 servers[4]; /* current servers */
} *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO:READ QUEUE STATUS NEW of Q=0x%lx", obj.id));
memset(xdata, 0, sizeof(*xdata));
U32_TO_BE32(obj.id, xdata->id);
data_len=sizeof(struct XDATA);
uint32 q_id = GET_BE32(rdata);
int status;
int entries;
int servers;
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;
case 0x81 : { /* Get Queue Job List */
@ -1203,6 +1321,37 @@ static void handle_fxx(int gelen, int func)
data_len=sizeof(struct XDATA);
}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 */
XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV"));
/* !!!!!! TODO completition=0xc6 (no rights) */
@ -1283,14 +1432,18 @@ static void handle_fxx(int gelen, int func)
#if 0
case 0xfd : /* Send Console Broadcast (new) */
return(-1); /* nicht erkannt */
break;
#endif
default : completition = 0xfb; /* not known here */
break;
} /* switch */
} else if (func == 0x19) { /* logout */
write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL);
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;
U16_TO_BE16(0x3333, ncpresponse->type);
@ -1346,8 +1499,11 @@ static void handle_bind_calls(uint8 *p)
static void reinit_nwbind(void)
{
int org_internal_act=internal_act;
get_ini_debug(NWBIND);
internal_act=1;
(void)nw_fill_standard(NULL, NULL);
internal_act=org_internal_act;
sync_dbm();
}
@ -1561,7 +1717,8 @@ int main(int argc, char *argv[])
t_close(ipx_out_fd);
}
}
sync_dbm();
internal_act=1;
nw_exit_dbm();
xfree(connections);
XDPRINTF((2,0, "LEAVE nwbind"));
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 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -28,13 +28,10 @@
#include "nwvolume.h"
#include "nwfile.h"
#include "connect.h"
#include "nwqueue.h"
#include "nwqconn.h"
#include "namspace.h"
#include "nwconn.h"
IPX_IO_RW ipx_io;
int use_ipx_io=0;
int act_connection = 0;
int act_pid = 0;
@ -92,8 +89,8 @@ typedef struct {
struct t_unitdata ud;
ipxAddr_t to_addr;
uint8 *recv_buf; /* complete data buf for burst read requests
* must be 24 byte more allocated
uint8 *recv_buf; /* complete data buf for burst read requests
* must be 24 byte more allocated
* than max_recv_size !
*/
@ -108,9 +105,9 @@ static BURST_W *burst_w=NULL;
static void set_program_title(char *s)
{
memset(prog_title, 0, 49);
if (s&&*s)
if (s&&*s)
strmaxcpy(prog_title, s, 48);
else
else
strcpy(prog_title, "()");
}
@ -541,8 +538,8 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
}
}
completition = (uint8)-result;
} else if (*p == 0x19){
/* Set Directory Information
} else if (*p == 0x19){
/* Set Directory Information
* Modifies basic directory information as creation date and
* 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 {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
uint8 dir_handle;
uint8 creation_date[2];
uint8 dir_handle;
uint8 creation_date[2];
uint8 creation_time[2];
uint8 owner_id[4];
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 */
XDPRINTF((5, 0, "Remove vol restrictions"));
return(-2); /* nwbind must do prehandling */
} else if (*p == 0x25){
/* Set Entry, Set Directory File Information
} else if (*p == 0x25){
/* Set Entry, Set Directory File Information
* sets or changes the file or directory information to the
* values entered in 'Change Bits'.
*/
/* NO REPLY */
/* ncopy use this call */
/* TODO !!!!!!!!!!!!!!!!!!!! */
do_druck++;
} else if (*p == 0x26) { /* Scan file or Dir for ext trustees */
int sequenz = (int)*(p+2); /* trustee sequenz */
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 if (*p == 0x2e){ /* RENAME DATEI */
completition = 0xfb; /* TODO: !!! */
} else if (*p == 0x2f){ /* Fill namespace buffer */
completition = 0xfb; /* TODO: !!! */
/* ncopy use this call */
#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){
/* Get Name Space Directory Entry */
int volume = (int) *(p+1);
@ -929,11 +934,54 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
break;
case 0x68: /* create queue job and file old */
case 0x69: /* close file and start queue old ?? */
case 0x79: /* create queue job and file */
case 0x7f: /* close file and start queue */
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 */
XDPRINTF((2,0, "TODO: Map Directory Number TO PATH"));
completition = 0xff;
@ -957,6 +1005,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
break;
case 0x19 : /* logout, some of this call is handled in ncpserv. */
free_queue_jobs();
nw_free_handles(-1);
set_default_guid();
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 */
break;
case 0x20 : /* Semaphore */
return(-1); /* handled by nwbind */
case 0x1a : /* lock 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=
min(max_burst_send_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->max_recv_size=
min(max_burst_recv_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);
#if 0
U32_TO_BE32(0x1600, burst_w->sendburst->delaytime);
#if 1
U32_TO_BE32(0x5ff22, burst_w->sendburst->delaytime);
#endif
U32_TO_BE32(burst_w->max_recv_size, xdata->max_recv_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 */
} else if (ncp_type == 0x1111) {
free_queue_jobs();
(void) nw_init_connect();
last_sequence = -9999;
} else {
@ -1771,7 +1822,7 @@ static void handle_after_bind()
case 0x68: /* create queue job and file old */
case 0x79: { /* create queue job and file */
/* nwbind must do prehandling */
/* nwbind made prehandling */
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */
@ -1779,22 +1830,15 @@ static void handle_after_bind()
uint8 queue_id[4]; /* Queue ID */
uint8 queue_job[280]; /* oldsize is 256 */
} *input = (struct INPUT *) (ncprequest);
struct RINPUT {
uint8 dir_nam_len; /* len of dirname */
uint8 dir_name[1];
} *rinput = (struct RINPUT *) (bindresponse);
int result = nw_creat_queue(
(int)ncpresponse->connection
| (((int)ncpresponse->high_connection) << 8),
input->queue_id,
input->queue_job,
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;
uint32 q_id = GET_BE32(input->queue_id);
uint8 *qjob = bindresponse;
int result = creat_queue_job(q_id, qjob,
responsedata,
(ufunc == 0x68) );
if (result > -1)
data_len=result;
else
completition = (uint8) -result;
}
break;
@ -1803,22 +1847,47 @@ static void handle_after_bind()
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 packetlen[2]; /* low high */
uint8 func; /* 0x7f or 0x6f */
uint8 func; /* 0x7f or 0x69 */
uint8 queue_id[4]; /* Queue ID */
uint8 job_id[4]; /* result from creat queue */
/* if 0x69 then only 2 byte ! */
} *input = (struct INPUT *) (ncprequest);
struct RINPUT {
uint8 client_area[152];
uint8 prc_len; /* len of printcommand */
uint8 prc[1]; /* printcommand */
} *rinput = (struct RINPUT *) (bindresponse);
int result = nw_close_file_queue(input->queue_id,
input->job_id,
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_job2(q_id, job_id,
rinput->client_area,
rinput->prc,
rinput->prc_len);
if (result < 0) completition = (uint8)-result;
}
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;
}
}
@ -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+1, sb->ack_seq);
U32_TO_BE32(size, sb->burstsize);
while (size) {
int sendsize=min(size, burst_w->max_burst_data_size);
int flags=0;
@ -1901,8 +1970,8 @@ static void handle_burst(BURSTPACKET *bp, int len)
struct REQ {
uint8 function[4]; /* lo-hi 1=READ, 2=WRITE */
uint8 fhandle[4]; /* from open file */
uint8 reserved1[6]; /* all zero */
uint8 reserved2[2]; /* ??? c8,0 od. c9,f0 */
uint8 reserved1[4]; /* all zero */
uint8 reserved2[4]; /* ??? c8,0 od. c9,f0 */
uint8 file_offset[4]; /* HI-LO */
uint8 file_size [4]; /* HI-LO */
uint8 data[2]; /* only Write */
@ -1923,9 +1992,13 @@ static void handle_burst(BURSTPACKET *bp, int len)
*/
uint8 readbytes[4]; /* hi-lo */
} *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),
fsize, foffset);
if (zusatz) {
XDPRINTF((1, 0, "foffset=%d, fsize=%d", foffset, fsize));
}
if (size > -1) {
U32_TO_32(0, xdata->resultcode);
U32_TO_BE32(size, xdata->readbytes);
@ -1948,7 +2021,10 @@ static void handle_burst(BURSTPACKET *bp, int len)
burst_w->burst_sequence = burstsequence;
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 */
int missing=GET_BE16(bp->missing);
uint8 *p=(uint8*)(bp+1);
@ -2013,11 +2089,11 @@ static void set_sig(void)
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)) {
fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n");
exit(1);
}
}
prog_title=argv[3];
setuid(0);
setgid(0);
@ -2027,7 +2103,7 @@ int main(int argc, char **argv)
XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%d",
father_pid, *(argv+2), act_connection));
adr_to_ipx_addr(&from_addr, *(argv+2));
if (nw_init_connect()) exit(1);
act_pid = getpid();
@ -2044,9 +2120,6 @@ int main(int argc, char **argv)
int conn = act_connection;
int result = ioctl(0, SIOCIPXNCPCONN, &conn);
XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result));
#if 0
if (result == 1) use_ipx_io++;
#endif
}
# endif
# endif
@ -2069,27 +2142,10 @@ int main(int argc, char **argv)
ncpresponse->connection = (uint8)act_connection;
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();
while (fl_get_int >= 0) {
int data_len ;
#ifdef SIOCIPXNCPCONN
if (use_ipx_io)
data_len = ioctl(0, SIOCIPXNCPCONN+1, &ipx_io);
else
#endif
data_len = read(0, readbuff, sizeof(readbuff));
int data_len = read(0, readbuff, sizeof(readbuff));
/* this read is a pipe or a socket read,
* depending on CALL_NWCONN_OVER_SOCKET
*/

View File

@ -1,23 +1,6 @@
/* nwconn.h 01-Aug-97 */
#ifndef _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_pid;
#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
*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
#include "net.h"
#include "nwdbm.h"
#include "nwcrypt.h"
#include "nwqueue.h"
#include "dirent.h"
#ifdef LINUX
@ -60,7 +61,7 @@ uint32 network_serial_nmbr=(uint32)NETWORK_SERIAL_NMBR;
uint16 network_appl_nmbr=(uint16)NETWORK_APPL_NMBR;
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_downshift=0; /* is SYS downshift */
@ -153,10 +154,33 @@ void sync_dbm()
#ifdef USE_GDBM
# define firstkey() gdbm_firstkey(my_dbm)
# define nextkey(key) gdbm_nextkey(my_dbm, key)
static datum firstkey(void)
{
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 fetch(key) gdbm_fetch(my_dbm, key)
# define store(key, content) gdbm_store(my_dbm, key, content, GDBM_REPLACE)
#else
# define firstkey() dbm_firstkey(my_dbm)
@ -218,11 +242,11 @@ int find_obj_id(NETOBJ *o)
int result;
XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x", o->name,(int)o->type));
if ((result=handle_iobj(0, o)) == 0) {
result = -0xff;
if (!dbminit(FNOBJ)){
key.dsize = NETOBJ_KEY_SIZE;
key.dptr = (char*)o;
data = fetch(key);
result = -0xff;
if (data.dptr != NULL){
NETOBJ *obj=(NETOBJ*)data.dptr;
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",
o->name, (int)o->type, o->id));
}
} else result = -0xff;
}
dbmclose();
if (!result)
return(0);
@ -827,6 +851,17 @@ int nw_delete_property(int object_type,
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,
uint8 *object_name, int object_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) {
result=strlen(buff);
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));
}
return(result);
}
@ -1078,6 +1114,19 @@ static int nw_create_obj_prop(uint32 obj_id, NETPROP *prop)
prop->id = p->id;
prop->obj_id = obj_id;
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;
} else founds[p->id]++;
}
@ -1515,6 +1564,7 @@ int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr)
return(result);
}
static int nw_new_add_prop_member(uint32 obj_id, char *propname,
int propflags, int propsecurity,
uint32 member_id)
@ -1534,13 +1584,19 @@ static int nw_new_add_prop_member(uint32 obj_id, char *propname,
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;
while (NULL != (p=strchr(p+1, '/'))) {
*p = '\0';
if (!mkdir(unixname, mode))
chmod(unixname, mode);
else if (flags&1){
struct stat stb;
if (!stat(unixname, &stb))
chmod(unixname, stb.st_mode|0111);
}
*p='/';
}
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");
if (stat(fname, &stbuff)){
(void)get_div_pathes(fname, NULL, 1, NULL);
xmkdir(fname, 0700);
nwdbm_mkdir(fname, 0700, 0);
(void)get_div_pathes(fname, fn, 1, ".dir");
}
if (always || stat(fname, &stbuff)){
@ -1573,30 +1629,54 @@ static void create_nw_db(char *fn, int always)
chmod(fname, 0600);
}
static void add_pr_queue(uint32 q_id,
char *q_name, char *q_directory,
char *q_command,
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));
q_id =
nw_new_obj_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31,
nw_new_obj_prop(q_id, NULL, 0, 0, 0,
"Q_DIRECTORY", P_FL_ITEM, 0x31,
q_directory, strlen(q_directory), 1);
/* this is mars_nwe own property to handle the print job !!! */
nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 ,
/* this is mars_nwe own property to handle the print job direct !!! */
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_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_OPERATORS", P_FL_STAT, 0x31, su_id);
#if 0
nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_SERVERS", P_FL_SET, 0x31,
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)
@ -1610,7 +1690,7 @@ static void add_user_2_unx(uint32 u_id, char *unname)
{
if (unname && *unname)
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);
}
@ -1703,7 +1783,7 @@ static int get_sys_unixname(uint8 *unixname, uint8 *sysname, uint8 *sysentry)
*(pp+1) = '\0';
if (stat(unixname, &statb) < 0)
xmkdir(unixname, 0777);
nwdbm_mkdir(unixname, 0777, 1);
if (stat(unixname, &statb) < 0 || !S_ISDIR(statb.st_mode)) {
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 & 2 = always modify uid/gid, permission */
/* flags & 4 = always add x flag to upper dirs */
{
struct stat stb;
strcpy((char*)pp, fn);
if (downshift) downstr(pp);
else upstr(pp);
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);
else {
chmod(unixname, permiss);
@ -1734,10 +1815,22 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags,
chown(unixname, uid, gid);
XDPRINTF((1, 0, "Created dir '%s'", unixname));
}
} else if (flags&2) {
chmod(unixname, permiss);
if (uid >-1 && gid > -1)
chown(unixname, uid, gid);
} else {
if (flags&4) { /* add 'x' flag */
char *p=unixname;
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) {
pp += strlen(pp);
@ -1748,24 +1841,30 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags,
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 buf1[20];
uint8 *p = fndir+sys_unixnamlen;
uint8 *pp;
uint8 *p1;
int l;
DIR *f;
memcpy(fndir, sys_unixname, sys_unixnamlen);
/* SYS/MAIL */
l=sprintf(p,"/mail/%x", (int)objid);
pp=p+l;
if (!sys_downshift)
memcpy(p,"/mail/", 6);
p1=p+6;
l=sprintf(buf1,"../%x", (int)objid)-3;
memcpy(p1, buf1+3, l+1);
pp=p1+l;
*pp='\0';
if (!sys_downshift) {
upstr(p);
upstr(buf1);
}
(void)mkdir(fndir, 0733);
(void)chmod(fndir, 0733);
(void)chown(fndir, uid, gid);
if ((f=opendir(fndir)) != (DIR*)NULL) {
struct dirent* dirbuff;
*pp='/';
@ -1778,24 +1877,35 @@ static void correct_user_dirs(uint32 objid, int uid, int gid)
}
}
}
*pp='\0';
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)
{
NETOBJ obj;
obj.id = id;
if ((MYPASSWD*)NULL == nw_getpwnam(id) && !nw_get_obj(&obj)){
struct passwd *pw;
uint8 unxname[50];
xstrcpy(unxname, obj.name);
downstr(unxname);
pw = getpwnam(unxname);
if (NULL != pw && pw->pw_uid) { /* only non root user */
add_user_2_unx(id, unxname);
correct_user_dirs(id, pw->pw_uid, pw->pw_gid);
if (!nw_get_obj(&obj)){
MYPASSWD *mpw=nw_getpwnam(id);
if ((MYPASSWD*)NULL == mpw){
struct passwd *pw;
uint8 unxname[50];
xstrcpy(unxname, obj.name);
downstr(unxname);
pw = getpwnam(unxname);
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];
uint32 su_id = 0x00000001;
uint32 ge_id = 0x01000001;
uint32 serv_id = 0x03000001;
uint32 server_id= 0x03000001;
uint32 q1_id = 0x0E000001;
#ifdef _MAR_TESTS_1
uint32 pserv_id = 0L;
#endif
FILE *f = open_nw_ini();
uint32 ps1_id = 0x0F000001;
FILE *f = open_nw_ini();
int auto_ins_user = 0;
char auto_ins_passwd[100];
int make_tests = 1;
@ -1844,13 +1952,16 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
} else if (8 == what) { /* entry8_flags */
entry8_flags = hextoi((char*)buff);
} else if (21 == what) { /* QUEUES */
char name[100];
char name[200];
char directory[200];
char command[200];
char *p=buff;
char *pp=name;
char c;
int state=0;
name[0]='\0';
directory[0]='\0';
command[0]='\0';
while (0 != (c = *p++)) {
if (c == 32 || c == '\t') {
if (!(state & 1)) {
@ -1862,21 +1973,59 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
if (state == 1) {
pp=directory;
state++;
} else {
} else if (state==3) {
strcpy(command, p-1);
if (*command) state++;
break;
}
}
}
*pp++ = c;
}
}
*pp='\0';
if (state == 4) {
if (*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);
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) {
/* SUPERVISOR, OTHERS and GROUPS*/
char nname[100];
@ -1927,10 +2076,12 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
fclose(f);
}
if (servername && adr) {
strmaxcpy(serverna, servername, MAX_SERVER_NAME);
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,
(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);
#endif
}
if (auto_ins_user) {
/* here Unix users will be inserted automaticly as mars_nwe users */
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));
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) {
uint8 unixname[512];
uint8 maildir[512];
uint8 sysname[256];
result = get_sys_unixname(unixname, sysname, sysentry);
if (result > -1) {
uint32 objs[2000]; /* max. 2000 User should be enough :) */
int ocount=0;
int downshift = (result & 1);
int unlen = strlen(unixname);
uint8 *pp = unixname+unlen;
uint8 *ppp = maildir+unlen;
memcpy(maildir, unixname, unlen+1);
uint32 objs[LOC_MAX_OBJS];
uint8 maildir[512];
int ocount=0;
uint8 *pp = unixname+unlen;
uint8 *ppp = maildir+unlen;
memcpy(maildir, unixname, unlen+1);
new_str(sys_unixname, unixname);
sys_downshift=downshift;
sys_unixnamlen=unlen;
test_add_dir(unixname, pp, 4, downshift,0755, 0,0, "LOGIN");
test_add_dir(unixname, pp, 0, downshift,0755, 0,0, "SYSTEM");
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");
test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "SYSTEM");
test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "PUBLIC");
ppp=test_add_dir(maildir, ppp, 1, downshift,0777, 0,0, "MAIL");
if (!dbminit(FNOBJ)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key);
if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr;
if (obj->type == 1 || obj->type == 3) {
objs[ocount++] = obj->id;
if (ocount == 2000) break;
}
if (!dbminit(FNOBJ)){
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
data = fetch(key);
if (data.dptr) {
NETOBJ *obj=(NETOBJ*)data.dptr;
if (obj->type == 1 || obj->type == 3) {
objs[ocount++] = obj->id;
if (ocount == LOC_MAX_OBJS) break;
}
}
}
dbmclose();
}
dbmclose();
while (ocount--) {
NETOBJ obj;
obj.id = objs[ocount];
nw_get_obj(&obj);
if (obj.type == 1) {
char sx[20];
int gid;
int uid;
sprintf(sx, "%x", (int)obj.id);
if (!get_guid(&gid, &uid, obj.id, NULL))
test_add_dir(maildir, ppp, 2, downshift, 0733, gid, uid, sx);
else
errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name);
while (ocount--) {
NETOBJ obj;
obj.id = objs[ocount];
nw_get_obj(&obj);
if (obj.type == 1) {
char sx[20];
int gid;
int uid;
sprintf(sx, "../%x", (int)obj.id);
if (!get_guid(&gid, &uid, obj.id, NULL)) {
test_add_dir(maildir, ppp, 2, downshift, 0733, gid, uid, sx+3);
memcpy(ppp, "user/", 5);
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 */
uint8 buff[300];
char *p;
int result=nw_get_q_dirname(obj.id, buff);
upstr(buff);
if (result > -1 && NULL != (p=strchr(buff, ':')) ) {
*p++='\0';
if (!strcmp(buff, sysname)) {
test_add_dir(unixname, pp, 2, downshift, 0770, 0, 0, p);
} else
errorp(0, "Warning:queue dir not on first SYS",
"Queue=%s, Volume=%s", obj.name, sysname);
} else if (obj.type == 3) { /* print queue */
uint8 buff[300];
char *p;
result=nw_get_q_dirname(obj.id, buff);
upstr(buff);
if (result > -1 && NULL != (p=strchr(buff, ':')) ) {
*p++='\0';
if (!strcmp(buff, sysname)) {
test_add_dir(unixname, pp, 2|4, downshift, 0775, 0, 0, p);
} 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);
}
int nw_init_dbm(char *servername, ipxAddr_t *adr)
static void nw_init_dbm_1(char *servername, ipxAddr_t *adr)
/*
* routine inits bindery
* all dynamic objects and properties will be deleted.
@ -2122,11 +2281,22 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr)
dbmclose();
while (anz--) /* now delete dynamic properties */
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
#define MAX_OBJ_IDS 100000 /* should be enough */
@ -2392,14 +2562,3 @@ int do_import_dbm(char *path)
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
*
* 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 *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,
uint8 *object_name, int object_namlen,
@ -162,6 +164,8 @@ extern int nw_scan_property(NETPROP *prop,
int prop_namlen,
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);
@ -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_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 int test_allow_password_change(uint32 id);
extern int nw_fill_standard(char *servername, ipxAddr_t *adr);
extern int nw_init_dbm(char *servername, ipxAddr_t *adr);
extern void nw_exit_dbm(void);
extern int do_export_dbm(char *path);
extern int do_import_dbm(char *path);
#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
*
* 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];
#define HOFFS 0
#define USE_NEW_FD 1
static int count_fhandles=0;
#if USE_NEW_FD
static int last_fhandle=HOFFS;
#endif
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;
while (++fhandle < count_fhandles) {
fh=&(file_handles[fhandle]);
@ -54,13 +63,27 @@ static int new_file_handle(uint8 *unixname, int task)
break;
} else fh=NULL;
}
if (fh == NULL) {
if (count_fhandles < MAX_FILE_HANDLES_CONN) {
fh=&(file_handles[count_fhandles]);
fhandle = ++count_fhandles;
} else {
XDPRINTF((1, 0, "No more free file handles"));
return(0); /* no free handle anymore */
#if USE_NEW_FD
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 */
@ -74,31 +97,12 @@ static int new_file_handle(uint8 *unixname, int task)
fh->f = NULL;
XDPRINTF((5, 0, "new_file_handle=%d, count_fhandles=%d, fn=%s",
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);
}
static int free_file_handle(int fhandle)
{
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)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) {
@ -125,11 +129,13 @@ static int free_file_handle(int fhandle)
}
}
fh->fd = -1;
#if !USE_NEW_FD
while (count_fhandles > fhandle
&& file_handles[count_fhandles-1].fd == -1
&& !(file_handles[count_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) {
count_fhandles--;
}
#endif
result=0;
}
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)
free_file_handle(k);
count_fhandles = HOFFS;
#if USE_NEW_FD
last_fhandle = HOFFS;
#endif
} else {
/* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */
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)
@ -185,8 +190,9 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
* creatmode: 0 = open
* | 1 = creat (ever)
* | 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 ??
*
* 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 dowrite = ((access & 2) || creatmode) ? 1 : 0;
int dowrite = ((access & 2) || (creatmode & 3) ) ? 1 : 0;
if (fhandle > HOFFS){
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
int completition = 0; /* first ok */
@ -220,7 +226,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
int did_grpchange = 0;
if (dowrite && (voloptions & VOL_OPTION_READONLY)) {
completition = (creatmode) ? -0x84 : -0x94;
completition = (creatmode&3) ? -0x84 : -0x94;
} else if (acc > -1) {
/* do exist */
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`",
fh->fname));
} else
completition = (creatmode) ? -0x84 : -0x94;
completition = (creatmode&3) ? -0x84 : -0x94;
} else
completition = (creatmode) ? -0x84 : -0x94;
completition = (creatmode&3) ? -0x84 : -0x94;
} else if (!(acc & R_OK) && !(creatmode & 0x8) )
completition = -0x93;
@ -267,7 +273,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
}
} else
completition= -0xff;
} else if ( (voloptions & VOL_OPTION_IS_PIPE) || !creatmode) {
} else if ( (voloptions & VOL_OPTION_IS_PIPE) || !(creatmode&3) ) {
/* must exist, but don't */
completition=-0xff;
} else {
@ -326,7 +332,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
}
} else {
/* <========= this is NOT a PIPE Volume ====================> */
if (creatmode) { /* creat File */
if (creatmode&0x3) { /* creat File */
if (creatmode & 0x2) { /* creatnew */
XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->fname, fhandle));
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;
}
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",
fh->fd, attrib, access, fh->fname, fhandle));
if (fh->fd < 0)
@ -601,7 +616,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite)
act_connection, act_pid);
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)
@ -613,6 +628,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
int readsize=size;
#if 1
if (-1 == (size = read(fh->fd, data, readsize)) ) {
int k=2;
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)));
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 (fh->f->flags & 1) return(-0x57);
fh->f->flags |= 1;
}
#endif
} else if (use_mmap && fh->p_mmap) {
while (1) {
if (offset < fh->size_mmap) {
@ -641,7 +671,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
}
} /* while */
} else {
if (use_ipx_io || fh->offd != (long)offset) {
if (fh->offd != (long)offset) {
fh->offd=lseek(fh->fd, offset, SEEK_SET);
if (fh->offd < 0) {
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 ((size = read(fh->fd, data, size)) > -1) {
fh->offd+=(long)size;
if (use_ipx_io) {
ipx_io.fh_r=fhandle+1;
ipx_io.fd_r=fh->fd;
}
} else {
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 */
return(size ? write(fh->fd, data, size) : 0);
} else {
if (use_ipx_io || fh->offd != (long)offset)
if (fh->offd != (long)offset)
fh->offd = lseek(fh->fd, offset, SEEK_SET);
if (size) {
if (fh->offd > -1L) {
size = write(fh->fd, data, 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;
return(size);
} else { /* truncate FILE */

View File

@ -1,7 +1,7 @@
/* nwfile.h 21-Jul-97 */
#ifndef _NWFILE_H_
#define _NWFILE_H_
#include "nwqueue.h"
#include "extpipe.h"
typedef struct {
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_
#define _NWQUEUE_H_
#include "queuedef.h"
/* enhanced pipe handling */
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 nw_get_q_dirname(uint32 q_id, uint8 *buff);
extern int ext_pclose(FILE_PIPE *fp);
extern FILE_PIPE *ext_popen(char *command, int uid, int gid);
extern int nw_creat_queue_job(int connection, int task, uint32 object_id,
uint32 q_id, uint8 *q_job, uint8 *responsedata,
int old_call);
/* queues */
typedef struct {
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];
extern int nw_close_queue_job(uint32 q_id, int job_id,
uint8 *responsedata);
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]; /* ?? 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 */
extern int nw_get_queue_status(uint32 q_id, int *status, int *entries,
int *servers, int server_ids[], int server_conns[]);
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];
uint8 job_bez[50]; /* "LPT1 Catch" */
uint8 client_area[152];
} QUEUE_JOB;
extern int nw_get_q_job_entry(uint32 q_id, int job_id,
uint8 *responsedata, int old_call);
extern int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata);
extern int nw_get_queue_job_file_size(uint32 q_id, int job_id);
typedef struct {
uint8 client_connection;
uint8 client_task;
uint8 client_id[4];
uint8 target_id[4]; /* 0xff, 0xff, 0xff, 0xff */
uint8 target_execute_time[6]; /* all 0xff */
uint8 job_entry_time[6]; /* all zero */
uint8 job_id[2]; /* ?? alles 0 HI-LOW */
uint8 job_typ[2]; /* z.B. Printform HI-LOW */
uint8 job_position; /* zero */
uint8 job_control_flags; /* z.B 0x10 */
/* 0x80 operator hold flag */
/* 0x40 user hold flag */
/* 0x20 entry open flag */
/* 0x10 service restart flag */
/* 0x08 autostart flag */
extern int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id);
uint8 job_file_name[14]; /* len + DOS filename */
uint8 job_file_handle[6];
uint8 server_station;
uint8 server_task;
uint8 server_id[4];
uint8 job_bez[50]; /* "LPT1 Catch" */
uint8 client_area[152];
} QUEUE_JOB_OLD; /* before 3.11 */
/* ------------------ for queue servers ------------------- */
extern int nw_attach_server_to_queue(uint32 user_id,
int connection,
uint32 q_id);
typedef struct {
uint8 version; /* normal 0x0 */
uint8 tabsize; /* normal 0x8 */
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_detach_server_from_queue(uint32 user_id,
int connection,
uint32 q_id);
extern int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
uint8 *dirname, int dir_nam_len, int old_call);
extern int nw_service_queue_job(uint32 user_id, int connection, int task,
uint32 q_id, int job_typ,
uint8 *responsedata, int old_call);
extern int nw_close_file_queue(uint8 *queue_id,
uint8 *job_id,
uint8 *prc, int prc_len);
extern int nw_finish_abort_queue_job(int mode, uint32 user_id, int connection,
uint32 q_id, int job_id);
extern void exit_queues(void);
extern void init_queues(uint8 *unixname, int unixname_len,
int downshift, uint8 *sysname);
#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
*
* This program is free software; you can redistribute it and/or modify
@ -34,6 +34,7 @@
NW_VOL *nw_volumes=NULL;
int used_nw_volumes=0;
int loaded_namespaces=0;
uint8 *home_dir=NULL;
int home_dir_len=0;
char *path_vol_inodes_cache=NULL;
@ -78,7 +79,8 @@ void nw_init_volumes(FILE *f)
}
}
rewind(f);
used_nw_volumes = 0;
used_nw_volumes = 0;
loaded_namespaces = 0;
new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache");
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
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) {
NW_VOL *vol=&(nw_volumes[used_nw_volumes]);
vol->options = VOL_NAMESPACE_DOS;
loaded_namespaces |= VOL_NAMESPACE_DOS;
up_fn(sysname);
new_str(vol->sysname, sysname);
if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') {
@ -133,10 +136,12 @@ void nw_init_volumes(FILE *f)
case 'O' : vol->options
|= VOL_NAMESPACE_OS2;
loaded_namespaces |= VOL_NAMESPACE_OS2;
break;
case 'N' : vol->options
|= VOL_NAMESPACE_NFS;
loaded_namespaces |= VOL_NAMESPACE_NFS;
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
*
* 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 int used_nw_volumes;
extern int loaded_namespaces;
extern uint8 *home_dir;
extern int home_dir_len;
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;
if (nw_debug >= dlevel) {
if (use_syslog==1) {
char buf[2048]; /* should be ever big enough */
char *pb=buf;
char *buf;
char *pb;
if (buffered) {
strcpy(buf, buffered);
xfree(buffered);
pb+=strlen(buf);
buf=buffered;
pb=buf+strlen(buffered);
buffered=NULL;
} else {
pb=buf=xmalloc(2048);
}
if (p) {
int l;
@ -143,9 +145,10 @@ static char *buffered=NULL;
closelog();
} else {
int l=strlen(buf);
buffered=xmalloc(l+1);
strcpy(buffered, buf);
buffered=xmalloc(l+2048);
memcpy(buffered, buf, l+1);
}
xfree(buf);
} else {
if (!(mode & 1))
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_spool=NULL;
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) {
case 0 : wpath = PATHNAME_PROGS; break;
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) {
new_str(path_bindery, locbuf);
} else
new_str(path_bindery, PATHNAME_BINDERY);
}
wpath = path_bindery;
wpath = path_bindery;
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';
return(buff);
}
@ -375,7 +393,7 @@ void get_debug_level(uint8 *buf)
char dummy;
if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1)
sscanf(buf2, "%lx", &debug_mask);
}
}
}
}
@ -390,7 +408,7 @@ void get_ini_debug(int module)
*/
{
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);
}
@ -466,6 +484,19 @@ void init_tools(int module, int options)
if (!strcmp(logfilename, "syslog"))
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 */
int fd=fork();
if (fd) exit((fd > 0) ? 0 : 1);