mars_nwe-0.99.pl01
This commit is contained in:
parent
fbd3b13b23
commit
51b8e80774
@ -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
|
||||
|
||||
|
5
doc/BUGS
5
doc/BUGS
@ -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.
|
||||
|
13
doc/CHANGES
13
doc/CHANGES
@ -1,6 +1,6 @@
|
||||
Sorry, this is in German only.
|
||||
User important notes are in the NEWS file.
|
||||
Aenderungen in mars_nwe bis zum : 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
4
doc/FAQS
4
doc/FAQS
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
4
doc/NEWS
4
doc/NEWS
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
166
extpipe.c
Normal 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
16
extpipe.h
Normal 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
|
15
makefile.unx
15
makefile.unx
@ -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)
|
||||
|
@ -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;
|
||||
|
196
namspace.c
196
namspace.c
@ -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,14 +967,23 @@ 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 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;
|
||||
@ -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,16 +1582,105 @@ static int nw_open_creat_file_or_dir(
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int nw_delete_file_dir(int namespace, int searchattrib,
|
||||
NW_HPATH *nwp)
|
||||
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 */
|
||||
{
|
||||
int result = build_base(namespace, nwp, nwp->pathes, 0, NULL);
|
||||
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 {
|
||||
int result;
|
||||
if (S_ISDIR(dbe->nwpath.statb.st_mode)) {
|
||||
result = rmdir(unname);
|
||||
if (result < 0) {
|
||||
@ -1597,7 +1696,22 @@ static int nw_delete_file_dir(int namespace, int searchattrib,
|
||||
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)
|
||||
{
|
||||
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];
|
||||
if (get_volume_options(dbe->nwpath.volume) &
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
329
nwbind.c
329
nwbind.c
@ -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,16 +217,25 @@ 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){
|
||||
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);
|
||||
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;
|
||||
@ -242,8 +247,8 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
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;
|
||||
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;
|
||||
*/
|
||||
}
|
||||
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
28
nwbind.h
Normal 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
|
182
nwconn.c
182
nwconn.c
@ -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;
|
||||
|
||||
@ -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,
|
||||
uint32 q_id = GET_BE32(input->queue_id);
|
||||
uint8 *qjob = bindresponse;
|
||||
int result = creat_queue_job(q_id, qjob,
|
||||
responsedata,
|
||||
(ufunc == 0x68) );
|
||||
if (!result) {
|
||||
data_len = (ufunc == 0x68) ? 54 : 78;
|
||||
memcpy(responsedata, input->queue_job, data_len);
|
||||
} else completition= (uint8)-result;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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 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);
|
||||
@ -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
|
||||
*/
|
||||
|
19
nwconn.h
19
nwconn.h
@ -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
|
||||
|
319
nwdbm.c
319
nwdbm.c
@ -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 !!! */
|
||||
/* 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,11 +1815,23 @@ 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) {
|
||||
} 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);
|
||||
*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,16 +1877,24 @@ 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)){
|
||||
if (!nw_get_obj(&obj)){
|
||||
MYPASSWD *mpw=nw_getpwnam(id);
|
||||
if ((MYPASSWD*)NULL == mpw){
|
||||
struct passwd *pw;
|
||||
uint8 unxname[50];
|
||||
xstrcpy(unxname, obj.name);
|
||||
@ -1795,7 +1902,10 @@ void test_ins_unx_user(uint32 id)
|
||||
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);
|
||||
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,11 +1916,9 @@ 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
|
||||
uint32 ps1_id = 0x0F000001;
|
||||
FILE *f = open_nw_ini();
|
||||
int auto_ins_user = 0;
|
||||
char auto_ins_passwd[100];
|
||||
@ -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,9 +1973,8 @@ 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;
|
||||
}
|
||||
}
|
||||
@ -1872,11 +1982,50 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
}
|
||||
}
|
||||
*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,29 +2141,30 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
memset(auto_ins_passwd, 0, sizeof(auto_ins_passwd));
|
||||
|
||||
if (*sysentry) {
|
||||
int result = 0;
|
||||
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 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) {
|
||||
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, 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");
|
||||
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");
|
||||
|
||||
if (!dbminit(FNOBJ)){
|
||||
for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) {
|
||||
@ -2020,7 +2173,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
NETOBJ *obj=(NETOBJ*)data.dptr;
|
||||
if (obj->type == 1 || obj->type == 3) {
|
||||
objs[ocount++] = obj->id;
|
||||
if (ocount == 2000) break;
|
||||
if (ocount == LOC_MAX_OBJS) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2035,37 +2188,43 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
|
||||
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
|
||||
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);
|
||||
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);
|
||||
test_add_dir(unixname, pp, 2|4, downshift, 0775, 0, 0, p);
|
||||
} else
|
||||
errorp(0, "Warning:queue dir not on first SYS",
|
||||
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
12
nwdbm.h
@ -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
|
||||
|
110
nwfile.c
110
nwfile.c
@ -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,15 +63,29 @@ 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 {
|
||||
#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 */
|
||||
fh->task = task;
|
||||
fh->fd = -2;
|
||||
@ -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 */
|
||||
|
2
nwfile.h
2
nwfile.h
@ -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
317
nwqconn.c
Normal 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
23
nwqconn.h
Normal 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
|
111
nwqueue.h
111
nwqueue.h
@ -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
|
||||
|
@ -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;
|
||||
@ -79,6 +80,7 @@ void nw_init_volumes(FILE *f)
|
||||
}
|
||||
rewind(f);
|
||||
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;
|
||||
|
@ -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
78
queuedef.h
Normal 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
259
sema.c
Normal 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
9
sema.h
Normal 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
|
45
tools.c
45
tools.c
@ -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, ... )
|
||||
{
|
||||
@ -306,6 +310,20 @@ char *get_div_pathes(char *buff, char *name, int what, char *p, ... )
|
||||
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);
|
||||
}
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user