diff --git a/connect.c b/connect.c index 33b120f..c64cef1 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 11-Jun-97 */ +/* connect.c 29-Jul-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -26,7 +26,8 @@ */ int use_mmap=USE_MMAP; -int tells_server_version=1; +int tells_server_version=1; /* defaults to 3.11 */ +int server_version_flags=0; int max_burst_send_size=0x2000; int max_burst_recv_size=0x2000; @@ -264,6 +265,12 @@ void reset_guid(void) set_guid(act_gid, act_uid); } +void reseteuid(void) +{ + if (seteuid(act_uid)) + reset_guid(); +} + void set_act_obj_id(uint32 obj_id) { act_obj_id=obj_id; @@ -1138,7 +1145,7 @@ int un_nw_rights(struct stat *stb) static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { - int voloptions=get_volume_options(nwpath->volume, 1); + int voloptions=get_volume_options(nwpath->volume); strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); f->attrib=0; /* d->name could be too long */ up_fn(f->name); @@ -1185,12 +1192,7 @@ static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs) char unname[256]; strcpy(unname, build_unix_name(nwpath, 0)); XDPRINTF((5,0,"DELETE FILE unname:%s:", unname)); - if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_IS_PIPE) - return(0); /* don't delete 'pipe commands' */ - else if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_READONLY) - return(-0x8a); /* don't delete 'readonly' */ - if (!unlink(unname)) return(0); - return(-0x8a); /* NO Delete Privileges */ + return(nw_unlink(nwpath->volume, unname)); } int nw_delete_datei(int dir_handle, uint8 *data, int len) @@ -1212,7 +1214,7 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf; int voloption; strcpy(unname, build_unix_name(nwpath, 0)); - if ((voloption = get_volume_options(nwpath->volume, 1)) & VOL_OPTION_IS_PIPE){ + if ((voloption = get_volume_options(nwpath->volume)) & VOL_OPTION_IS_PIPE){ ;; /* don't change 'pipe commands' */ } else if (voloption & VOL_OPTION_READONLY) { result=(-0x8c); /* no modify rights */ @@ -1286,7 +1288,7 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) if (completition > -1) { char unname[256]; strcpy(unname, build_unix_name(&nwpath, 2)); - if (get_volume_options(nwpath.volume, 1) & VOL_OPTION_READONLY) + if (get_volume_options(nwpath.volume) & VOL_OPTION_READONLY) return(mode ? -0x84 : -0x8a); if (mode) { XDPRINTF((5,0,"MKDIR dirname:%s:", unname)); @@ -1336,8 +1338,8 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, if (completition > -1) { completition=conn_get_kpl_path(&zielpath, zdirhandle, z, zlen, 0); if (completition > -1) { - int optq = get_volume_options(quellpath.volume, 1); - int optz = get_volume_options(zielpath.volume, 1); + int optq = get_volume_options(quellpath.volume); + int optz = get_volume_options(zielpath.volume); if ((optq & VOL_OPTION_IS_PIPE) || (optz & VOL_OPTION_IS_PIPE)) completition = -0x8b; else if ((optq & VOL_OPTION_READONLY) || @@ -1386,8 +1388,8 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, completition=conn_get_kpl_path(&zielpath, dir_handle, z, zlen, 0); #endif if (completition > -1) { - int optq = get_volume_options(quellpath.volume, 1); - int optz = get_volume_options(zielpath.volume, 1); + int optq = get_volume_options(quellpath.volume); + int optz = get_volume_options(zielpath.volume); if ((optq & VOL_OPTION_IS_PIPE) || (optz & VOL_OPTION_IS_PIPE)) completition = -0x8b; else if ((optq & VOL_OPTION_READONLY) || @@ -1507,7 +1509,10 @@ int nw_init_connect(void) while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { if (what == 6) { /* version */ - tells_server_version = atoi(buff); + if (2 != sscanf((char*)buff, "%d %x", + &tells_server_version, + &server_version_flags)) + server_version_flags=0; } else if (what == 8) { /* entry8_flags */ entry8_flags = hextoi((char*)buff); } else if (what == 9) { /* GID */ @@ -1543,7 +1548,7 @@ int nw_init_connect(void) errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); return(-1); } - if (get_volume_options(0, 1) & VOL_OPTION_DOWNSHIFT) + if (get_volume_options(0) & VOL_OPTION_DOWNSHIFT) down_fn(nwlogin.path); if (stat(build_unix_name(&nwlogin, 0), &stbuff)) { errorp(1, "Stat error LOGIN Directory, Abort !!", @@ -1988,7 +1993,7 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, { uint8 spath[14]; uint32 nw_owner=get_file_owner(stb); - int voloptions=get_volume_options(volume, 1); + int voloptions=get_volume_options(volume); f->namlen=min(strlen((char*)path), 12); strmaxcpy(spath, path, 12); up_fn(spath); diff --git a/connect.h b/connect.h index eb49e33..8eaad62 100644 --- a/connect.h +++ b/connect.h @@ -1,4 +1,4 @@ -/* connect.h 02-Jun-97 */ +/* connect.h 29-Jul-97 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ @@ -108,6 +108,7 @@ typedef struct { extern int use_mmap; extern int tells_server_version; +extern int server_version_flags; extern int max_burst_send_size; extern int max_burst_recv_size; @@ -219,6 +220,7 @@ extern int conn_get_kpl_unxname(char *unixname, extern void set_default_guid(void); extern void set_guid(int gid, int uid); extern void reset_guid(void); +extern void reseteuid(void); extern void set_act_obj_id(uint32 obj_id); extern int in_act_groups(gid_t gid); extern int get_real_access(struct stat *stb); diff --git a/debmask.h b/debmask.h index 7485f18..25e059d 100644 --- a/debmask.h +++ b/debmask.h @@ -1,4 +1,4 @@ -/* debmask.h: 18-Jun-97 */ +/* debmask.h: 23-Jul-97 */ #ifndef _DEBMASK_H_ #define _DEBMASK_H_ /* @@ -8,11 +8,12 @@ */ /* NWCONN */ -#define D_FH_OPEN 1 /* file open/close */ -#define D_FH_LOCK 2 /* file lock/unlock */ -#define D_FH_FLUSH 4 /* file flushes */ +#define D_FH_OPEN 1 /* file open/close */ +#define D_FH_LOCK 2 /* file lock/unlock */ +#define D_FH_FLUSH 4 /* file flushes */ -#define D_FN_NAMES 8 +#define D_FN_NAMES 8 +#define D_FN_SEARCH 0x10 /* file search */ #endif diff --git a/doc/CHANGES b/doc/CHANGES index ebdfbed..4c44e09 100644 --- a/doc/CHANGES +++ b/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 : 07-Jul-97 +Aenderungen in mars_nwe bis zum : 14-Jul-97 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -302,14 +302,14 @@ Erste 'oeffentliche' Version - Max. moegliche Connections auf > 255 erhoeht. Muss aber noch richtig getestet werden. - Dateimatchroutine OS/2 namespace wiederum abgeaendert. - Es wurde bei Matchcode '0xff * 0xff 0xae 0xff *' keine Datei + Es wurde bei Matchcode '0xff * 0xff 0xae 0xff *' keine Datei ohne '.' gefunden. - Attribute von 'Pipe Commands' ist nun Shareble. Dadurch sollten Client Bufferungen verhindert werden. - einige Konstanten aus config.h sind nun auch zur Laufzeit aenderbar. ab section 60 in ini/conf file. -- Konstanten MAX_NW_ROUTES, MAX_NW_SERVERS, MAX_RIP_ENTRIES, - MAX_NET_DEVICES werden nicht mehr benoetigt, da entsprechende +- Konstanten MAX_NW_ROUTES, MAX_NW_SERVERS, MAX_RIP_ENTRIES, + MAX_NET_DEVICES werden nicht mehr benoetigt, da entsprechende Arrays nun bei Bedarf dynamisch wachsen. - nw_2_un_time Routine setzt nun auch die Sekunden korrekt. Hinweis/Patch von Csoma Csaba. @@ -317,13 +317,35 @@ Erste 'oeffentliche' Version ab Offset gelockt. ( von Peter Gerhard ) - In connect.c, build_verz_name() Fehlerabfang fuer 'falsche Dateinamen' korrigiert. (Victor Khimenko schickte patch) - Es war moeglich auf 9 stellige (ohne Punkt) Verzeichnissnamen + Es war moeglich auf 9 stellige (ohne Punkt) Verzeichnissnamen zuzugreifen. - examples/unxcomm.c korrigiert. - es wird nun der Login Name oder '()' fuer attached unter ps angezeigt. - in routine nw_2_un_time() wird nun tm_isdst korrekterweise auf -1 gesetzt. -- dynamisches Aktivieren/Deaktivieren von Interfaces verbessert. +- dynamisches Aktivieren/Deaktivieren von Interfaces verbessert. <----- ^^^^^^^^^^ pl11 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +^^^^^^^^^^ VERSION 0.98 ^^^^^^^^ +- Einfachen Plattencache fuer Inode->Pfad Zuweisungen eingebaut. + Nun muesste Client-32 funktionieren. +- Verwende nun defaultmaessig gdbm.h falls gdbm lib vorhanden. + (Ambrose Li) +- Namespace Routine nw_modify_file_dir korrigiert. ! +- Locking result code abgeaendert von 0xfd auf 0xfe. + (Przemyslaw Czerpak) +- Aus nw_commit_file den flush ausgebaut, da dieser alle + Locks aus der Datei entfernte. (Przemyslaw Czerpak) +- Result Code bei Openfile (lock error) von 0xfe auf 0x80 abgeaendert. +- Namespace Suchroutine wiederum abgeaendert. +- nwbind entfernt nun beim Beenden austehende Eintraege in utmp. + (Ambrose Li) +- Bindery Code Security verbessert. +- Bindery Account Erweiterung von Mark Robson eingebaut. +- Unterstuetzung 'slow nets' verbessert. (fuer CL/Wolters). +- 'Home Volumes' werden nun generell als 'remountable' behandelt. +- Bindery Pfad kann nun in section 45 bestimmt werden. +- File-sharing abgeaendert. +- Internen Router Code fuer SAP Anfragen des internen Netzes (slist usw.) + korrigiert. +<----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index a7acb49..210488a 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -22,6 +22,9 @@ Hardy Buchholz Csoma Csaba testings+bugfixes +Przemyslaw Czerpak + testings+bugfixes + Ales Dryak his linware gave the kick @@ -40,6 +43,9 @@ Ruedi Kneubuehler Volker Lendecke helps distributing +Ambrose Li + gave hints, patches, docs + James B. MacLean many testings+notes @@ -52,6 +58,9 @@ Matt Paley Jiri A. Randus testing bindery code +Mark Robson + fixed bindery security hole and added bindery options + Gregory Steuck testings and errorreports diff --git a/doc/FAQS b/doc/FAQS index 878e581..dc601f6 100644 --- a/doc/FAQS +++ b/doc/FAQS @@ -1,18 +1,36 @@ -last updated: 11-Apr-97 -Q: I don't exaclty understand the meaning of some ponits in nw.ini: +last updated: 14-Jul-97 + +Q: Which DOS programs from the real Netware do I need? +A: For a minimal configuration you only need LOGIN.EXE. + However, it makes sense to also install the following programs: + MAP.EXE : Drive mapping program. + CAPTURE.EXE : Printer redirection program. + SYSCON.EXE : Administration tool. + + There is also a DOS client program in development, which will allow + the use of mars_nwe without the original Novell DOS tools. + +Q: I don't exactly understand the meaning of some points in nw.ini: 12,13 - What will happen if I will not put PASSWORD here? Will it take it from + What will happen if I do not put PASSWORD here? Will it take it from /etc/passwd? I want it to be so. -A: This passwords will be stored (crypted) into bindery to can handle - the crypted login call from a standarrd Novell client. +A: These passwords will be stored (crypted) into bindery to can handle + the crypted login call from a standard Novell client. + + If you do not put a password in section 12, the supervisor login will + be completely disabled; if you do not put passwords in section 13, + the users will be able to login with no password: in neither case + will passwords from /etc/passwd be used, except you are working with + unencrypted passwords ( see section 7 ). + Q: What role plays: 15? What if I will no supply passwd here? -A: This is for automatic inserting UNIX Users as mars_nwe users. - All of these automatic inserted users will get the password +A: This is for automatic inserting UNIX users as mars_nwe users. + All of these automatically inserted users will get the password as the crypted bindery password. -Q: File write will not work under WIN3.1, WfW +Q: File write does not work under Win3.1, WfW A: Try updating C:\WINDOWS\SYSTEM\STORAGE.DLL. I find that earlier versions of this file evince the problem you describe under Windows 3.1 and 3.11. Precisely when this problem went away in STORAGE.DLL I don't @@ -22,10 +40,10 @@ A: Try updating C:\WINDOWS\SYSTEM\STORAGE.DLL. I find that earlier Q: I do not have longfilenamesupport. A: Give the volume the 'O' flag. Set section 6 in nwserv.conf to > 0. - Win95, by default, does not use long filenames on a netware 3.11 + Win95, by default, does not use long filenames on a Netware 3.11 server. This is documented in the resource kit help file and elsewhere. You should read that to find out the ramifications, but - with real netware I've had good luck using the recommended registry + with real Netware I've had good luck using the recommended registry settings. Here is a registry import file: REGEDIT4 [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR] @@ -33,15 +51,15 @@ A: Give the volume the 'O' flag. 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 +A: Make sure that all Eth-devices have an assigned IP address, even if they are only used for IPX. -Q: I have arcnet cards and I dont find the frame-typ TRXNET. -A: The correct frame typ is handled by the arcnet driver. - You should use the 'dummy frametyp' 802.3. +Q: I have arcnet cards and I don't find the frame type TRXNET. +A: The correct frame type is handled by the arcnet driver. + You should use the 'dummy frame type' 802.3. Q: The CONFIG_IPX_INTERN kernel option is *not* set but - when I start 'nwserv' as root it sais: + when I start 'nwserv' as root it says: !! NWSERV 0:PANIC !! NWSERV 0:!! configuration error !!: mars_nwe don't run with kernel 'full internal net'. @@ -52,10 +70,10 @@ A: Sorry but mars_nwe can recognize this setting only at compile time, settings. Q: What is an easy way to get a 'clean' nwserv.conf file without comments. -A: do a 'make showconf' in the mars_nwserv directory or do a +A: Do a 'make showconf' in the mars_nwe directory or do a 'grep "^[ \t]*[0-9]" /etc/nwserv.conf' -Q: Which frametyp should I use (Ethernet_ii, 802.2, SNAP or 802.3) ? +Q: Which frame type should I use (Ethernet_II, 802.2, SNAP or 802.3) ? A: Use Ethernet_II on a new network as it can carry anything and everything (AFAIK) and doesn't have any of the potential disadvantages of the rest. diff --git a/doc/NEWS b/doc/NEWS index 532801a..16a9252 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,15 @@ +------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 + or removed time to time when no mars_nwe connection is up. +- Some bindery code from Mark Robson, important security fixes !! + Allows the supervisor to disable accounts with SYSCON + Allows the supervisor to put expiry dates on with SYSCON +- Handling of file-sharing changed. (see also new flag in section 8) +- first (only test)version with 'Burst-Mode'. + config.h -> ENABLE_BURSTMODE + Section 6: version-"spoofing" must be set > '1' (3.12). + new section 30: Burst mode values. ------07-Jul-97--- 0.98.pl11 --------- - section 201 enhanced -> syslogd - new section 50: filenametranslation by Victor Khimenko. diff --git a/doc/PPP b/doc/PPP new file mode 100644 index 0000000..6f36078 --- /dev/null +++ b/doc/PPP @@ -0,0 +1,64 @@ +/* some notes for using PPP */ +Mars_nwe works well with ppp and ippp Devices. +This files describes example for ppp device. +The file PPP.isdn describes example for ippp device. + +Simple sample config files for a ppp server using ppp0 as ppp device. +We configure TCP-IP and IPX ppp connections. + +Notes: +- ppp must be compiled into kernel or must be loaded as module. +- mgetty has to be compiled with "-DAUTO_PPP" for this to work. +- pppd has to be compiled with IPX. + + +[nwserv.conf] + 4 0x0 ppp0 AUTO 7 # ticks > 6 to filter RIP/SAP. + # 'auto device' + +[/usr/etc/mgetty+sendfax/login.config] +/AutoPPP/ - ppp /usr/sbin/pppd auth + +[/etc/ppp/options] +#--- first we configure IPX of course ;-) --- +#use RIP/SAP routing +ipx-routing 2 +#ipx-network must be uniq ! +ipx-network 0xabc01 +# IPX-NODE local:remote +ipx-node 1:2 +# +#--- TCP/IP is usefull too. --- +# IP-address +#local:remote +192.168.60.29:192.168.60.230 +#we do not let ppp set defaultroute +#we set routes in ip-up / ip-down scripts. +-defaultroute + +[/etc/ppp/ipx-up] +#!/bin/sh +# let nwserv update internal tables +/sbin/nwserv -u + +[/etc/ppp/ipx-down] +#!/bin/sh +# let nwserv update internal tables +/sbin/nwserv -u + +[/etc/ppp/ip-up] +#!/bin/sh +PPPDEV=$1 +REMOTEADDR=$5 +# set a host route to ppp client +/sbin/route add $REMOTEADDR dev $PPPDEV + +[/etc/ppp/ip-down] +#!/bin/sh +PPPDEV=$1 +REMOTEADDR=$5 +# remove host route to ppp client +/sbin/route del $REMOTEADDR + + + diff --git a/doc/PPP.isdn b/doc/PPP.isdn new file mode 100644 index 0000000..eadc4d7 --- /dev/null +++ b/doc/PPP.isdn @@ -0,0 +1,144 @@ +/* some notes for using IPPP */ +Mars_nwe works well with ppp and ippp Devices. +This files describes example for ippp device. +The file PPP describes example for ppp device. + +Simple sample config files for a ppp server using ippp0 as ppp device. +We configure TCP-IP and IPX ppp connections. + +Notes: +- isdn must be configured to use synchron ppp (ippp). +- ipppd has to be compiled with IPX support. + + +[nwserv.conf] + 4 0x0 ippp0 AUTO 7 # ticks > 6 to filter RIP/SAP. + # 'auto device' + +[/etc/isdnrc] +#!/bin/sh +# example start script for ippp connections + +# set our local ISDN MSM for incoming PPP calls. +PPP_MSM=93082 + +ISDNDEV= +PPPID= +PPP_NR= + +preset_ppp() +{ + PPP_NR=$2 + ISDNDEV="ippp$PPP_NR" + PPPID=`ps -xa | fgrep ipppd | fgrep $ISDNDEV | awk '{print $1}'` + + if [ "$1" = 'start' ] ; then + if [ "$PPPID" != "" ] ; then + preset_ppp stop $PPP_NR + fi + isdnctrl addif $ISDNDEV + isdnctrl l2_prot $ISDNDEV hdlc + isdnctrl l3_prot $ISDNDEV trans + isdnctrl eaz $ISDNDEV $PPP_MSM + isdnctrl chargehup $ISDNDEV on + # default 19 sec huptimeout + isdnctrl huptimeout $ISDNDEV 19 + # we accept all incoming telnos + isdnctrl secure $ISDNDEV off + isdnctrl ihup $ISDNDEV off + isdnctrl callback $ISDNDEV off + isdnctrl encap $ISDNDEV syncppp + ifconfig $ISDNDEV up + ifconfig $ISDNDEV 1.1.1.1 + fi + + if [ "$1" = 'stop' ] ; then + if [ "$PPPID" != "" ] ; then + kill -TERM $PPPID + sleep 1 + kill -9 $PPPID + fi + PPPID=`ps -xa | fgrep ipppd | fgrep $ISDNDEV | awk '{print $1}'` + if [ "$PPPID" != "" ] ; then + kill -TERM $PPPID + sleep 1 + kill -9 $PPPID + fi + ifconfig $ISDNDEV down + isdnctrl delif $ISDNDEV + fi +} + +handle_gast_ppp() +# gast PPP -> PPP_MSM +{ + preset_ppp $1 0 + if [ "$1" = 'start' ] ; then + /sbin/ipppd \ + $ISDNDEV \ + user gast \ + name gast \ + 192.168.60.29:192.168.60.231 \ + +ipx \ + ipx-network 0xabc02 \ + ipx-node fcfcabba0001:fcfcabba0002 \ + -vjccomp \ + mru 1524 \ + mtu 1500 \ + -bsdcomp \ + -defaultroute \ + auth \ + & + fi +} + +case "$1" in + +'start' + handle_gast_ppp $1 + ;; +'stop') + handle_gast_ppp $1 + ;; + +*) usage: $0 start|stop + ;; +esac + +[/etc/ppp/ioptions] +# empty + + +[/etc/ppp/ipx-up] +#!/bin/sh +# let nwserv update internal tables +/sbin/nwserv -u + +[/etc/ppp/ipx-down] +#!/bin/sh +# let nwserv update internal tables +/sbin/nwserv -u + +[/etc/ppp/ip-up] +#!/bin/sh +PPPDEV=$1 +REMOTEADDR=$5 +# set a host route to ppp client +/sbin/route add $REMOTEADDR dev $PPPDEV + +[/etc/ppp/ip-down] +#!/bin/sh +PPPDEV=$1 +REMOTEADDR=$5 +# remove host route to ppp client +/sbin/route del $REMOTEADDR + +[/etc/ppp/chap-secrets] +gast * gast +* gast gast + +[/etc/ppp/pap-secrets] +gast * gast +* gast gast + + diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 5d9930a..3129ae4 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98.pl11 -Entered-date: 07-Jul-97 +Version: 0.99.pl0 +Entered-date: 31-Jul-97 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-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 - 200kB mars_nwe-0.98.pl11.tgz + 240kB mars_nwe-0.99.pl0.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 diff --git a/examples/config.h b/examples/config.h index 15a66df..4d54b52 100644 --- a/examples/config.h +++ b/examples/config.h @@ -76,7 +76,7 @@ #define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */ /* main idea from Victor Khimenko */ - /* in 0.98.pl11 still NOT working !! */ + /* in 0.99.pl0 still NOT working !! */ /* <--------------- next is for linux only ----------------------------> */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ diff --git a/examples/mk.li b/examples/mk.li index f035532..395bcc0 100755 --- a/examples/mk.li +++ b/examples/mk.li @@ -1,5 +1,5 @@ #!/bin/sh -# mk.li 19-Oct-96 +# mk.li 10-Jul-97 # please edit this file ! mk() @@ -22,15 +22,6 @@ mk() print_error() { - if [ "$UNX" = 'linux' ]; then - if [ ! -f /usr/include/ndbm.h ] ; then - echo "-------------------------------------------------------------" - echo "probably you have a broken Linux installation because" - echo "'/usr/include/ndbm.h' the include file for the Linux database" - echo "is missing." - echo "-------------------------------------------------------------" - fi - fi echo "" echo "The errors are also reported in '$ERRFILE'" echo "=============================================================" @@ -93,6 +84,15 @@ fi ;; esac +## BEGIN try to pass around what the dbm is to the compiler (acli 19970709) +case "$NDBMLIB" in +*gdbm*) + HOSTCFLAGS="$HOSTCFLAGS -DUSE_GDBM" + ;; +esac +## END + + export CC export CPP export CFLAGS diff --git a/examples/nw.ini b/examples/nw.ini index e44cb8e..255e2d1 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -2,7 +2,7 @@ # This is the configuration-file for "mars_nwe", a free netware-emulator # for Linux. # -# last changed: 07-Jul-97 +# last changed: 20-Jul-97 # !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !! # # since version 0.98.pl11: @@ -77,7 +77,6 @@ # and you don't set 'i' all files _must_ be upper-case) # m removable volume (e.g. cd-roms) or volumes, which # should be remountable when mars_nwe is running. -# Should also be used for 'HOME' volumes. # r volume is read-only and always reports "0 byte free" # (this is intended for copies of CD-ROMs on harddisks) # o (lowercase o) @@ -98,7 +97,7 @@ # Examples: # 1 SYS /var/local/nwe/SYS k # 1 CDROM /cdrom kmr -# 1 HOME ~ km +# 1 HOME ~ k 1 SYS /u3/SYS/ k @@ -223,10 +222,13 @@ # routers, the shortest path can be determined by summing up # all ticks for every route and compare the results. # (1 tick = 1/18th second), default=1 +# Note: If ticks > 6 then the internal router handles +# RIP/SAP specially. (RIP/SAP filtering) +# # !! NOTE !! # Automatic detection in this section means that ipx-interfaces which # are created by other instances than the server/router, -# e.g. pppd or ipx_interface, will be detected and inserted/removed +# e.g. pppd, ipppd or ipx_interface, will be detected and inserted/removed # in internal device/routing table at runtime. # # Automatic kernel creation of interfaces can be switched on in section 5. @@ -239,6 +241,12 @@ # 4 0x0 * AUTO 1 # auto detection of all ipx-interfaces. # 4 0x0 eth0 AUTO 1 # auto detection of eth0 frames. # 4 0x0 eth0 802.2 1 # auto detection of eth0 frame 802.2. +# +# Note: If ticks > 6 then the internal router handles RIP/SAP specially. +# (RIP/SAP filtering) +# 4 0x0 isdn0 802.3 7 # auto isdn interface with ethernet encap. +# 4 0x0 ippp0 AUTO 7 # auto ippp0 (isdn ppp) interface. +# 4 0x0 ppp0 AUTO 7 # auto detection of ppp0 interface. 4 0x22 eth0 ethernet_ii 1 4 0x0 * AUTO 1 @@ -269,23 +277,27 @@ # missing yet. # ------------------------------------------------------------------------- # Syntax: -# 6 SERVER_VERSION +# 6 SERVER_VERSION [FLAGS] # # SERVER_VERSION: the version-number reported to DOS-clients # 0 Version 2.15 (was default till version 0.98.pl7) # 1 Version 3.11 (is default now) -# 2 Version 3.12 (burst mode is not implemented yet) +# 2 Version 3.12 # # If you want to use longfilenamesupport and/or namespace routines # you should set this section to '1' or '2' # And you should read doc/FAQS. -# If you want to test Burst mode this section must be set to '2' -# and in config.h you must set ENABLE_BURSTMODE to 1. # +# FLAGS: some flags +# &1 enable burst mode connections. +# If you want to test Burst mode this flag must be set. +# and in config.h you must set ENABLE_BURSTMODE to 1. +# +# other flags may follow. +# value will be interpreted as hex value. # ------------------------------------------------------------------------- # - -6 1 +6 1 0x0 # ========================================================================= @@ -341,6 +353,10 @@ # # 0x8 ignore station/time restrictions for supervisor. # +# 0x10 allows deleting a file even if the file is opened by +# other process. +# ( this was standard before mars_nwe-0.99.pl0 ) +# # other flags may follow. # value will be interpreted as hex value. @@ -581,6 +597,18 @@ # 30 0x2000 0x2000 +# ========================================================================= +# Section 40ff: Some pathes (optional) +# +# ------------------------------------------------------------------------- +# 40 = path for vol/dev/inode->path cache, needed for client-32,namespace +40 /var/spool/nwserv/.volcache +# 41 = path for share/lock files +41 /var/spool/nwserv/.locks +# +# 45 = path for bindery file's +45 /etc + # ========================================================================= # Section 50: Conversion tables by Victor Khimenko # Tables for DOS->Unix names translation & upper/lowercase translations diff --git a/makefile.unx b/makefile.unx index 9154ee9..7f24d27 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 24-Apr-97 +#makefile.unx 09-Jul-97 #endif VPATH=$(V_VPATH) @@ -8,8 +8,8 @@ O=.o C=.c V_H=0 -V_L=98 -P_L=11 +V_L=99 +P_L=0 #define D_P_L 1 DISTRIB=mars_nwe @@ -113,7 +113,7 @@ 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) +nwqueue$(O) nameos2$(O) nwfname$(O) nwshare$(O) OBJ4= $(OBJ1) OBJ5= $(OBJ1) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) @@ -266,6 +266,8 @@ n_distrib: n_diff ; mv $(DISTRIBF).tgz /tmp/x/. \ ; cp -a $(DISTRIB)/doc/$(DISTRIB).lsm /tmp/x/. \ ; cd $(OBJDIR) ) + -rm -f /tmp/mars_nwe.tgz + ln -s /tmp/x/$(DISTRIBF).tgz /tmp/mars_nwe.tgz n_distrib_bin: cd $(VPATH) && (/usr/local/bin/cdar cb /tmp/mars_nwb.cda \ diff --git a/namspace.c b/namspace.c index d3b2a6d..040a0b2 100644 --- a/namspace.c +++ b/namspace.c @@ -1,7 +1,7 @@ -/* namspace.c 14-May-97 : NameSpace Services, mars_nwe */ +/* namspace.c 30-Jul-97 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ -/* Its still very dirty, but it should work fairly well */ +/* Its still dirty, but it should work fairly well */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -30,6 +30,7 @@ #include "nwfname.h" #include "nwvolume.h" #include "connect.h" +#include "nwconn.h" #include "nwfile.h" #include "unxfile.h" #include "namspace.h" @@ -41,6 +42,7 @@ #if 0 +/* for tests only */ # undef MAX_DIR_BASE_ENTRIES # define MAX_DIR_BASE_ENTRIES 10 #endif @@ -62,21 +64,74 @@ typedef struct { } DIR_SEARCH_STRUCT; typedef struct { - uint32 basehandle; + uint32 basehandle; int slot; /* act slot in table */ int locked; /* if locked then do not remove */ /* and do not move till end */ - - /* next is for Direktories, used by the search dir calls */ - off_t dirpos; /* last readdirpos */ - ino_t found_inode; /* last found inode at readdirpos*/ - int sequence; /* last sequence */ N_NW_PATH nwpath; } DIR_BASE_ENTRY; static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES]; static int anz_dbe = 0; +#define MAX_DIR_SEARCH_HANDLES 10 + +#if MAX_DIR_SEARCH_HANDLES > 255 +# undef MAX_DIR_SEARCH_HANDLES +# define MAX_DIR_SEARCH_HANDLES 255 +#endif + +typedef struct { + int idle; + off_t dirpos; /* last readdirpos */ + ino_t found_inode; /* last found inode at readdirpos */ + int lastsequence; /* last sequence */ +} DIR_SEARCH_HANDLE; + +static DIR_SEARCH_HANDLE *dir_search_handles[MAX_DIR_SEARCH_HANDLES]; +static int count_dsh = 0; + +static uint32 new_search_handle(void) +{ + int k=count_dsh; + int foundfree=-1; + DIR_SEARCH_HANDLE *d; + while (k--) { + if (!dir_search_handles[k]) { + foundfree=k; + break; + } else dir_search_handles[k]->idle++; + } + if (foundfree < 0 && count_dsh < MAX_DIR_SEARCH_HANDLES) + foundfree=count_dsh++; + if (foundfree < 0) { + int idle=-1; + for (k=0; k < count_dsh; k++){ + if (dir_search_handles[k]->idle > idle) { + foundfree=k; + idle=dir_search_handles[k]->idle; + } + } + } else { + dir_search_handles[foundfree]= + (DIR_SEARCH_HANDLE*)xmalloc(sizeof(DIR_SEARCH_HANDLE)); + } + d=dir_search_handles[foundfree]; + memset(d, 0, sizeof(DIR_SEARCH_HANDLE)); + return((uint32) foundfree); +} + +#if 0 /* probably never needed */ +static void free_search_handle(uint32 handle) +{ + if (handle < count_dsh) { + xfree(dir_search_handles[handle]); + if (count_dsh == handle+1) + --count_dsh; + } +} +#endif + static void init_nwpath(N_NW_PATH *nwpath, int namespace) { nwpath->volume = -1; @@ -164,6 +219,47 @@ static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus, #define nwpath_2_unix2(nwpath, modus, extrabytes, extrastr) \ xnwpath_2_unix((nwpath), (modus), (extrabytes), extrastr) +char *debug_nwpath_name(N_NW_PATH *p) +/* only for debugging */ +{ +#if DO_DEBUG + static char *nwpathname=NULL; + char volname[300]; + int len; + if (nw_get_volume_name(p->volume, volname) < 1) + sprintf(volname, "<%d=NOT-OK>", (int)p->volume); + len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 40; + xfree(nwpathname); + nwpathname=xmalloc(len); + sprintf(nwpathname, "%d `%s:%s`,fn=`%s`", + p->namespace, volname, p->path, p->fn); +#else + static char nwpathname[2]; + nwpathname[0]='\0'; + nwpathname[1]='\0'; +#endif + return(nwpathname); +} + +static int nwp_stat(N_NW_PATH *nwpath, char *debstr) +{ + uint8 *uname=nwpath_2_unix1(nwpath, 2, 1); + int result=stat(uname, &(nwpath->statb)); + if (nw_debug) { + char xdebstr[2]; + if (!debstr) { + xdebstr[0]='\0'; + debstr = xdebstr; + } + XDPRINTF((4, 0, "nwp_stat:%s:%d,%s", + debstr, + result, + debug_nwpath_name(nwpath))); + } + xfree(uname); + return(result); +} + static int downsort_dbe_entries(int dbase) { DIR_BASE_ENTRY **dbep=&(dir_base[dbase]); @@ -181,27 +277,131 @@ static int downsort_dbe_entries(int dbase) return(dbase); } + +static void put_dbe_to_disk(DIR_BASE_ENTRY *dbe) +{ + char buf[255]; + char volname[100]; + int l; + uint8 inode_uc[4]; +#if 0 + int voloptions=get_volume_options(dbe->nwpath.volume); +#endif + if (nw_get_volume_name(dbe->nwpath.volume, volname) < 1) + return; + U32_TO_BE32(dbe->nwpath.statb.st_ino, inode_uc); + l=sprintf(buf, "%s/%s/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname, +#if 0 + (voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0, +#else + 0, +#endif + dbe->nwpath.statb.st_dev, + (int) inode_uc[0], + (int) inode_uc[1], + (int) inode_uc[2]); + + seteuid(0); + unx_xmkdir(buf, 0755); + sprintf(buf+l, "/%x", (int) inode_uc[3]); + unlink(buf); + symlink(dbe->nwpath.path, buf); + reseteuid(); +} + +static void del_dbe_from_disk(DIR_BASE_ENTRY *dbe) +{ + char buf[255]; + char volname[100]; + uint8 inode_uc[4]; +#if 0 + int voloptions=get_volume_options(dbe->nwpath.volume); +#endif + if (nw_get_volume_name(dbe->nwpath.volume, volname) < 1) + return; + U32_TO_BE32(dbe->nwpath.statb.st_ino, inode_uc); + sprintf(buf, "%s/%s/%x/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname, +#if 0 + (voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0, +#else + 0, +#endif + dbe->nwpath.statb.st_dev, + (int) inode_uc[0], + (int) inode_uc[1], + (int) inode_uc[2], + (int) inode_uc[3]); + seteuid(0); + unlink(buf); + reseteuid(); +} + + +static int get_dbe_data_from_disk(int volume, + int dev, int ino, uint8 *path, + struct stat *statb) +/* returns 0 if all ok */ +{ + char buf[255]; + char volname[100]; + int l; + uint8 inode_uc[4]; +#if 0 + int voloptions=get_volume_options(volume); +#endif + if (nw_get_volume_name(volume, volname) < 1) + return (-1); + U32_TO_BE32(ino, inode_uc); + sprintf(buf, "%s/%s/%x/%x/%x/%x/%x/%x", path_vol_inodes_cache, volname, +#if 0 + (voloptions & VOL_OPTION_IS_HOME) ? act_connection : 0, +#else + 0, +#endif + dev, + (int) inode_uc[0], + (int) inode_uc[1], + (int) inode_uc[2], + (int) inode_uc[3]); + l=readlink(buf, path, 511); + if (l > 0) { + path[l]='\0'; + return(0); + } + return(-1); +} + static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) /* returns new allocated dir_base_entry_pointer */ { int j =-1; - int to_use=-1; + int to_use_free=-1; + int to_use_file=-1; DIR_BASE_ENTRY *dbe; while (++j < anz_dbe && NULL != (dbe = dir_base[j])){ - if (j > 3 && !dbe->basehandle && !dbe->locked) - to_use=j; + if (j > 3 && !dbe->locked) { + if (!dbe->basehandle) + to_use_free=j; + else if (j > 10 && !S_ISDIR(dbe->nwpath.statb.st_mode)) + to_use_file=j; + } if (dbe->slot != j) { - XDPRINTF((0,0, "slot %d != %d", j, dbe->slot)); + errorp(0, "allocate_dbe_p", "slot %d != %d", dbe->slot); } } if (j == anz_dbe) { if (anz_dbe == MAX_DIR_BASE_ENTRIES) { - if (to_use > -1) { - j = to_use; + if (to_use_free > -1) { + j = to_use_free; + } else if (to_use_file > -1) { + j = to_use_file; + /* caching directories is more important than caching files */ } else { while (j && dir_base[--j]->locked) ;; } + if (S_ISDIR(dir_base[j]->nwpath.statb.st_mode)) + put_dbe_to_disk(dir_base[j]); xfree(dir_base[j]); } else anz_dbe++; @@ -230,38 +430,17 @@ static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe) /* routine touchs this entry and returns the new offset */ { int dbase = (NULL != dbe) ? dbe->slot : -1; - XDPRINTF((4, 0, "touch_handle_entry_p entry dbase=%d", dbase)); + XDPRINTF((7, 0, "touch_handle_entry_p entry dbase=%d", dbase)); if (dbase > 4) { dir_base[dbase] = NULL; dbase=downsort_dbe_entries(dbase); dir_base[dbase] = dbe; dbe->slot = dbase; } - XDPRINTF((4, 0, "touch_handle_entry_p return dbase=%d", dbase)); + XDPRINTF((7, 0, "touch_handle_entry_p return dbase=%d", dbase)); return(dbase); } -char *debug_nwpath_name(N_NW_PATH *p) -/* only for debugging */ -{ -#if DO_DEBUG - static char *nwpathname=NULL; - char volname[300]; - int len; - if (nw_get_volume_name(p->volume, volname) < 1) - sprintf(volname, "<%d=NOT-OK>", (int)p->volume); - len = strlen(volname) + strlen(p->path) + strlen(p->fn) + 40; - xfree(nwpathname); - nwpathname=xmalloc(len); - sprintf(nwpathname, "%d `%s:%s`,fn=`%s`", - p->namespace, volname, p->path, p->fn); -#else - static char nwpathname[2]; - nwpathname[0]='\0'; - nwpathname[1]='\0'; -#endif - return(nwpathname); -} static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) /* returns size of path components in bytes */ @@ -324,6 +503,7 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, int i=len; if (pp > nwpath->path) { /* not the first entry */ *pp = '/'; /* we must add a slash */ + if (*(nwpath->path+npbeg) == '/') ++npbeg; *++pp = '\0'; } @@ -398,7 +578,14 @@ leave_build_nwpath: } else if (nwpath->namespace == NAME_DOS) { dos2unixcharset(pp); pp+=npbeg; + + if (v->options & VOL_OPTION_DOWNSHIFT) + down_fn(pp); + else + up_fn(pp); + mangle_dos_name(v, unixname, pp); + if (nplen > 0) { unix2doscharset(pp); memcpy(nwpath->path+npbeg, pp, nplen); @@ -424,24 +611,6 @@ leave_build_nwpath: return(result); } -static int nwp_stat(N_NW_PATH *nwpath, char *debstr) -{ - uint8 *uname=nwpath_2_unix1(nwpath, 2, 1); - int result=stat(uname, &(nwpath->statb)); - if (nw_debug) { - char xdebstr[2]; - if (!debstr) { - xdebstr[0]='\0'; - debstr = xdebstr; - } - XDPRINTF((4, 0, "nwp_stat:%s:%d,%s", - debstr, - result, - debug_nwpath_name(nwpath))); - } - xfree(uname); - return(result); -} static uint32 name_2_base(N_NW_PATH *nwpath, int namespace, int no_stat) /* returns basehandle of path, or 0 if not exist !! */ @@ -460,7 +629,12 @@ static uint32 name_2_base(N_NW_PATH *nwpath, int namespace, int no_stat) } static int add_dbe_entry(int namspace, int volume, - uint32 basehandle, uint8 *path, struct stat *stb) + uint32 basehandle, uint8 *path, + struct stat *stb) +/* creats an dbe entry + * returns slot on success + * or errorcode +*/ { DIR_BASE_ENTRY *dbe=allocate_dbe_p(namspace); if (dbe) { @@ -472,6 +646,13 @@ static int add_dbe_entry(int namspace, int volume, } if (stb) memcpy(&(dbe->nwpath.statb), stb, sizeof(struct stat)); + else { + if (nwp_stat(&(dbe->nwpath), "add_dbe_entry")){ + del_dbe_from_disk(dbe); + free_dbe_p(dbe); + return(-0x9b); /* we use wrong path here */ + } + } return(dbe->slot); } return(-0x96); /* we use out of memory here */ @@ -503,10 +684,18 @@ static int find_base_entry(int volume, uint32 basehandle) /* now we test whether it is the root of volume */ if (0 < ino) { struct stat statb; + uint8 path[512]; + if (ino == get_volume_inode(volume, &statb)) { /* its the handle of the volumes root */ return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb)); } + + if (!get_dbe_data_from_disk(volume, dnm.dev, ino, path, &statb)) { + /* we found it on disk */ + return(add_dbe_entry(dnm.namespace, volume, basehandle, path, NULL)); + } + } XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x", volume, basehandle)); return(-0x9b); @@ -519,7 +708,7 @@ static int insert_get_base_entry(N_NW_PATH *nwpath, if (!basehandle && creatmode) { /* now creat the entry (file or dir) */ int result = 0; char *unname = nwpath_2_unix(nwpath, 2); - if (get_volume_options(nwpath->volume, 1) & + if (get_volume_options(nwpath->volume) & VOL_OPTION_READONLY) return(-0x8a); if (creatmode & FILE_ATTR_DIR) { @@ -608,6 +797,7 @@ static int build_base(int namespace, result=-0xff; if (!result) { nwpath->namespace = namespace; + if ((result = add_hpath_to_nwpath(nwpath, nwp, pathes)) > -1) { char *pp=strrchr((char*)nwpath->path, '/'); if (mode) { @@ -623,6 +813,7 @@ static int build_base(int namespace, nwpath->fn = (pp) ? (uint8*)pp+1 : nwpath->path; result = insert_get_base_entry(nwpath, namespace, 0); } + } return(result); } @@ -633,7 +824,7 @@ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname) int len=0; int pf=0; int is_ok=1; - int options=get_volume_options(e->nwpath.volume, 1); + int options=get_volume_options(e->nwpath.volume); for (; *ss; ss++){ if (*ss == '.') { if (pf++) { /* no 2. point */ @@ -772,8 +963,8 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, struct stat *stb=&(nwpath->statb); int result = 76; /* minimumsize */ uint32 owner = get_file_owner(stb); - int voloptions = get_volume_options(nwpath->volume, 1); - + int voloptions = get_volume_options(nwpath->volume); + memset(p, 0, result+2); if (infomask & INFO_MSK_DATA_STREAM_SPACE) { @@ -936,7 +1127,7 @@ static int nw_init_search(int namespace, *responsedata++ = dbe->nwpath.volume; U32_TO_32(dbe->basehandle, responsedata); responsedata+=4; - U32_TO_32(0L, responsedata); /* searchsequenz */ + memset(responsedata, 0xff, 4); /* INIT sequence */ result = 9; } XDPRINTF((3, 0, "nw_init_search path=%s, result=%d, basehandle=0x%x", @@ -1051,40 +1242,123 @@ static int namespace_fn_match(uint8 *s, uint8 *p, int namespace) } +static int search_match(struct dirent *dirbuff, + int vol_options, + int namespace, + int inode_search, /* do we search an inode */ + uint8 *entry, + int searchattrib, + uint8 *dname, + DIR_SEARCH_STRUCT *ds) + +/* returns 1 if match, 0= no match */ +{ + int flag=0; + if (dirbuff->d_ino && strlen(dirbuff->d_name) < 256) { + uint8 *name=(uint8*)(dirbuff->d_name); + struct stat statb; + if (namespace == NAME_DOS || namespace == NAME_OS2) { + strcpy(dname, name); + unix2doscharset(dname); + } else + strcpy(dname, name); + XDPRINTF((8,0,"search_match, Name='%s' dname='%s'", name, dname)); + if (!inode_search) { + if (namespace == NAME_DOS) { + flag = (*name != '.' && fn_dos_match(dname, entry, vol_options)); + } else if (namespace == NAME_OS2) { + flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) + && fn_os2_match(dname, entry, vol_options); + } else { + flag = (!strcmp(name, entry) + || namespace_fn_match(name, entry, namespace)); + } + } else + flag = (dirbuff->d_ino == inode_search); + + if (flag) { + strcpy(ds->kpath, name); + XDPRINTF((7,0,"search_match, Name found=%s unixname=%s", + name, ds->unixname)); + if (!stat(ds->unixname, &statb)) { + flag = (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; + if (!flag) { + if (S_ISDIR(statb.st_mode)) + flag=(searchattrib & FILE_ATTR_DIR); + else + flag = !(searchattrib & FILE_ATTR_DIR); + } + if (!flag) { + XDPRINTF((10, 0, "type = %s not ok searchattrib=0x%x", + S_ISDIR(statb.st_mode) ? "DIR" :"FILE" ,searchattrib)); + } + } else { + XDPRINTF((2,0,"search_match: stat error fn='%s'", + ds->unixname)); + } + *(ds->kpath) = '\0'; + } + } + return(flag); +} + int nw_search_file_dir(int namespace, int datastream, uint32 searchattrib, uint32 infomask, int *count, - int volume, uint32 basehandle, uint32 *sequence, + int volume, uint32 basehandle, uint32 *psequence, int len, uint8 *path, uint8 *info, int *perhaps_more) { #if 0 int max_counts = *count; #endif - int found = 0; int result = find_base_entry(volume, basehandle); + DIR_BASE_ENTRY *dest_dbe=NULL; + int sequence; *perhaps_more = 0; *count = 0; - if (len > 255) return(-0x9c); /* wrong path */ - if (result > -1) { + + MDEBUG(D_FN_SEARCH, { + char fname[300]; + strmaxcpy(fname, path, min(sizeof(fname)-1, len)); + xdprintf(1,0,"nwsfd:seqence=%d, base=%d, attrib=0x%x, fn=`%s`", + *psequence, basehandle, searchattrib, fname); + }) + if (len > 255) result=-0x9c; /* we say wrong path here */ + else if (result > -1) { + if (*psequence == MAX_U32) { + *psequence=new_search_handle(); + + MDEBUG(D_FN_SEARCH, { + xdprintf(1,0,"nwsfd:got new search seqence=%d", *psequence); + }) + + } + } + + sequence = *psequence >> 8; + *psequence &= 0xff; + + if (result > -1 && *psequence < count_dsh) { + DIR_SEARCH_HANDLE *dsh=dir_search_handles[*psequence]; DIR_BASE_ENTRY *dbe=dir_base[result]; DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258); + if (NULL != (ds->fdir = opendir(ds->unixname)) ) { - int lastsequence; 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; - struct stat statb; int dest_entry=-1; - int vol_options = get_volume_options(volume, 0); + int vol_options = get_volume_options(volume); ds->kpath = ds->unixname+strlen(ds->unixname); *(ds->kpath) = '/'; *(++(ds->kpath)) = '\0'; - dbe->locked++; + dbe->locked++; /* lock dbe */ + dsh->idle=0; /* touch dsh */ while (len--) { uint8 c=*path++; @@ -1099,7 +1373,7 @@ int nw_search_file_dir(int namespace, int datastream, } *pe='\0'; - if (!have_wild && is_ap && pe - is_ap == 3 && *is_ap== '_' + 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); @@ -1116,144 +1390,96 @@ int nw_search_file_dir(int namespace, int datastream, } XDPRINTF((5,0,"nw_s_f_d namsp=%d, sequence=%d, search='%s'", - namespace, *sequence, entry )); + namespace, sequence, entry )); - if (*sequence == MAX_U32) - *sequence=0L; - - lastsequence=dbe->sequence; - - if (!*sequence) { - if (have_wild) - dbe->sequence = 0; - dbe->dirpos = (off_t)0; + if ( (!sequence) || (sequence != dsh->lastsequence)) { + XDPRINTF((5, 0, "dirpos set to 0 dsh->lastsequence = %d, dirpos=%d", + dsh->lastsequence, dsh->dirpos)); + dsh->dirpos = (off_t)0; } - if (*sequence != dbe->sequence || dbe->dirpos < 1L) { - XDPRINTF((7, 0, "dirpos set to 0 dbe->sequence = %d, dirpos=%d", - dbe->sequence, dbe->dirpos)); - dbe->dirpos = (off_t)0; - lastsequence = 0; - } - seekdir(ds->fdir, dbe->dirpos); - - if ( ( (dirbuff=readdir(ds->fdir)) == NULL - || dirbuff->d_ino != dbe->found_inode ) && dbe->found_inode) { - lastsequence = 0; - seekdir(ds->fdir, 0L); - XDPRINTF((7, 0, "dirbuff->d_ino %d != dbe->found_inode=%d ", - (dirbuff)?dirbuff->d_ino:0, dbe->found_inode)); - dirbuff=NULL; - } else { - lastsequence++; - } - - if (dbe->sequence != *sequence || !dbe->found_inode - || dirbuff==NULL - || dbe->found_inode != dirbuff->d_ino) { - XDPRINTF((7, 0, "needed new")); - while (lastsequence <= *sequence - && (dirbuff=readdir(ds->fdir)) != NULL) { - lastsequence++; - if (dirbuff && dbe->found_inode - && dirbuff->d_ino == dbe->found_inode - && dbe->sequence == *sequence) /* perhaps dir shrunk */ - break; + if (dsh->dirpos) { + seekdir(ds->fdir, dsh->dirpos); + if (( (dirbuff=readdir(ds->fdir)) == NULL + || (dirbuff->d_ino != dsh->found_inode)) + && dsh->found_inode>0) { + seekdir(ds->fdir, 0L); + XDPRINTF((5, 0, "dirbuff->d_ino %d != dsh->found_inode=%d ", + (dirbuff)?dirbuff->d_ino:0, dsh->found_inode)); + dsh->lastsequence=0; + while((dirbuff=readdir(ds->fdir)) != NULL + && dirbuff->d_ino != dsh->found_inode) + dsh->lastsequence++; } + if (!dirbuff) /* inode not found */ + seekdir(ds->fdir, 0L); + } + if (dirbuff==NULL) { + dsh->lastsequence=0; + while ((dirbuff=readdir(ds->fdir)) != NULL + && dsh->lastsequence < sequence) + dsh->lastsequence++; } - dbe->dirpos = telldir(ds->fdir); + while (dirbuff!=NULL) { - uint8 *name=(uint8*)(dirbuff->d_name); - - if (dirbuff->d_ino && strlen((char*)name) < 256) { - int flag; - uint8 dname[256]; - if (namespace == NAME_DOS || namespace == NAME_OS2) { - strcpy(dname, name); - unix2doscharset(dname); - } else - strcpy(dname, name); - XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name)); - if (!inode_search) { - if (namespace == NAME_DOS) { - flag = (*name != '.' && fn_dos_match(dname, entry, vol_options)); - } else if (namespace == NAME_OS2) { - flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) - && fn_os2_match(dname, entry, vol_options); - } else { - flag = (!strcmp(name, entry) - || namespace_fn_match(name, entry, namespace)); - } - } else - flag = (dirbuff->d_ino == inode_search); - - if (flag) { - strcpy(ds->kpath, name); - XDPRINTF((15,0,"nw_search_file_dir Name found=%s unixname=%s", - name, ds->unixname)); - if (!stat(ds->unixname, &statb)) { - flag = (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; - if (!flag) { - if (S_ISDIR(statb.st_mode)) - flag=(searchattrib & FILE_ATTR_DIR); - else - flag = !(searchattrib & FILE_ATTR_DIR); - } - if (flag) { - if (!found) { - strcpy(entry, dname); - if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) { - found++; - break; - } else { - XDPRINTF((1, 0, "nw_search_file_dir:Cannot add entry '%s'", entry)); - } - } else { - found++; - break; - } - } else { - XDPRINTF((10, 0, "type = %s not ok searchattrib=0x%x", - S_ISDIR(statb.st_mode) ? "DIR" :"FILE" ,searchattrib)); - } - } else { - XDPRINTF((1,0,"nw_search_file_dir: stat error fn='%s'", - ds->unixname)); - } - *(ds->kpath) = '\0'; + uint8 dname[257]; + if (search_match( dirbuff, + vol_options, + namespace, + inode_search, + entry, + searchattrib, + dname, + ds)) { + if ((dest_entry = get_add_new_entry(dbe, namespace, dname, 0)) > -1) + break; + else { + XDPRINTF((2, 0, "nw_search_file_dir:Cannot add entry '%s'", entry)); } } /* if */ dirbuff = readdir(ds->fdir); - lastsequence++; + dsh->lastsequence++; } /* while */ *(ds->kpath) = '\0'; if (dest_entry > -1) { - DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry]; + dest_dbe=dir_base[dest_entry]; (void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir"); result = build_dir_info(dest_dbe, datastream, infomask |INFO_MSK_NAME_SPACE_INFO, info); *count=1; - *sequence = lastsequence; - dbe->dirpos = telldir(ds->fdir); - if (have_wild) { - dbe->sequence = lastsequence; - dirbuff = readdir(ds->fdir); - if (dirbuff) { + dsh->dirpos = telldir(ds->fdir); + dirbuff = readdir(ds->fdir); + dsh->found_inode=0; + *perhaps_more=0; + dsh->lastsequence++; /* set to next */ + while (dirbuff) { + uint8 dname[257]; + if (search_match( dirbuff, + vol_options, + namespace, + inode_search, + entry, + searchattrib, + dname, + ds)) { *perhaps_more=0xff; - dbe->found_inode=dirbuff->d_ino; - } else { - dbe->found_inode=0; - *perhaps_more=0; + dsh->found_inode=dirbuff->d_ino; + break; } - } else { - *perhaps_more=0; - } - XDPRINTF((5, 0, "more=%d, file=%s,next=%s", - *perhaps_more, dest_dbe->nwpath.path, dirbuff?dirbuff->d_name:"")); + dsh->dirpos = telldir(ds->fdir); + dirbuff = readdir(ds->fdir); + dsh->lastsequence++; + } /* while */ + *psequence |= (dsh->lastsequence << 8); + XDPRINTF((5, 0, "more=%d, sequence = 0x%x, file=%s,next=%s", + *perhaps_more, *psequence, dest_dbe->nwpath.path, + dirbuff?dirbuff->d_name:"")); } else { + dsh->idle = 1000; + dsh->dirpos = (off_t)0; result=-0xff; /* no files matching */ XDPRINTF((5, 0, "no files matching")); } @@ -1265,7 +1491,15 @@ int nw_search_file_dir(int namespace, int datastream, } xfree(ds->unixname); xfree(ds); - } + } else if (result > -1) result=-0xff; + MDEBUG(D_FN_SEARCH, { + char fname[300]; + strmaxcpy(fname, path, min(sizeof(fname-1), len)); + xdprintf(1, (result>-1)?2:0,"nwsfd:result=0x%x,more=%d ", result, *perhaps_more); + if (result>-1) { + xdprintf(1, 1,"found='%s'", (dest_dbe) ? (char*) (dest_dbe->nwpath.path) : "" ); + } + }) return(result); } @@ -1345,23 +1579,24 @@ static int nw_delete_file_dir(int namespace, int searchattrib, 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, 1) & + if (get_volume_options(dbe->nwpath.volume) & VOL_OPTION_READONLY) result = -0x8a; else { if (S_ISDIR(dbe->nwpath.statb.st_mode)) { - free_dbe_p(dbe); result = rmdir(unname); + if (result < 0) { + switch (errno) { + case EEXIST: result=-0xa0; /* dir not empty */ + default: result=-0x8a; /* No privilegs */ + } + } else { + result = 0; + free_dbe_p(dbe); + } } else { - if (-1 < (result = unlink(unname))) + if (-1 < (result = nw_unlink(dbe->nwpath.volume, unname))) free_dbe_p(dbe); } - if (result < 0) { - switch (errno) { - case EEXIST: result=-0xa0; /* dir not empty */ - default: result=-0x8a; /* No privilegs */ - } - } else - result = 0; } } return(result); @@ -1424,7 +1659,7 @@ static int nw_get_full_path_cookies(int namespace, uint8 *pp=lastpp; while (pp > dbe->nwpath.path && *--pp !='/');; if (*pp == '/') { - if (pp < dbe->nwpath.path + 2) ++done; + if (pp < dbe->nwpath.path + 1) ++done; pp++; l = lastpp-pp; lastpp = pp-1; @@ -1485,9 +1720,9 @@ static int nw_rename_file_dir(int namespace, uint8 *unname_d = (uint8*)nwpath_2_unix2(&(dbe_d->nwpath), 0, 1, last_part); - if (get_volume_options(dbe_s->nwpath.volume, 1) & + if (get_volume_options(dbe_s->nwpath.volume) & VOL_OPTION_READONLY) result= EROFS; - else if (get_volume_options(dbe_d->nwpath.volume, 1) & + else if (get_volume_options(dbe_d->nwpath.volume) & VOL_OPTION_READONLY) result= EROFS; else { @@ -1517,11 +1752,11 @@ static int nw_rename_file_dir(int namespace, } static int nw_modify_file_dir(int namespace, - NW_HPATH *nwp, uint8 *path, + NW_HPATH *nwp, uint8 *pathes, int searchattrib, uint32 infomask, DOS_MODIFY_INFO *dmi) { - int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + int result = build_base(namespace, nwp, pathes, 0, NULL); if (result > -1) { DIR_BASE_ENTRY *dbe=dir_base[result]; uint8 *uname=nwpath_2_unix1(&(dbe->nwpath), 2, 1); @@ -1617,7 +1852,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) memcpy(&nwpathstruct, p+2, sizeof(nwpathstruct)); result = nw_init_search(namespace, &nwpathstruct, - p+9, + p+9, /* pathes */ responsedata); } break; @@ -1831,20 +2066,18 @@ static int code = 0; uint8 anz_name_spaces; uint8 name_space_list[1]; } *xdata= (struct OUTPUT*)responsedata; - result=get_volume_options(volume, 0); - if (result >-1) { - xdata->anz_name_spaces = (uint8) 0; - if (result & VOL_NAMESPACE_DOS) - xdata->name_space_list[xdata->anz_name_spaces++] - = (uint8) NAME_DOS; - if (result & VOL_NAMESPACE_OS2) - xdata->name_space_list[xdata->anz_name_spaces++] - = (uint8) NAME_OS2; - if (result & VOL_NAMESPACE_NFS) - xdata->name_space_list[xdata->anz_name_spaces++] - = (uint8) NAME_NFS; - result=xdata->anz_name_spaces+1; - } + result=get_volume_options(volume); + xdata->anz_name_spaces = (uint8) 0; + if (result & VOL_NAMESPACE_DOS) + xdata->name_space_list[xdata->anz_name_spaces++] + = (uint8) NAME_DOS; + if (result & VOL_NAMESPACE_OS2) + xdata->name_space_list[xdata->anz_name_spaces++] + = (uint8) NAME_OS2; + if (result & VOL_NAMESPACE_NFS) + xdata->name_space_list[xdata->anz_name_spaces++] + = (uint8) NAME_NFS; + result=xdata->anz_name_spaces+1; } break; diff --git a/ncpserv.c b/ncpserv.c index 74ed5f3..b011e2f 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -1,4 +1,4 @@ -/* ncpserv.c 02-Jun-97 */ +/* ncpserv.c 29-Jul-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -31,9 +31,6 @@ static char my_nwname[50]; static time_t akttime; static int server_goes_down=0; static int ipx_out_fd=-1; -#if 0 -static int tells_server_version=1; -#endif static int sock_nwbind=-1; static int sock_echo =-1; static int highest_fd = 10; @@ -56,7 +53,7 @@ static int get_ini(int full) while (0 != (what =get_ini_entry(f, 0, buff, sizeof(buff)))) { if (60 == what && full) { /* max_connections */ max_connections=atoi((char*)buff); - if (max_connections < 5) + if (max_connections < 1) max_connections=MAX_CONNECTIONS; } else if (400 == what) { /* station file */ new_str(station_fn, buff); @@ -711,6 +708,8 @@ int main(int argc, char *argv[]) return(1); } get_ini(1); + if (max_connections < 1) + max_connections=1; connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION)); strncpy(my_nwname, argv[1], 48); my_nwname[47] = '\0'; diff --git a/net.h b/net.h index ba39c7a..272911c 100644 --- a/net.h +++ b/net.h @@ -179,7 +179,7 @@ extern int errno; #endif #ifndef PATHNAME_BINDERY -# define PATHNAME_BINDERY "." /* location of bindery files */ +# define PATHNAME_BINDERY "/etc" /* location of bindery files */ #endif #ifndef PATHNAME_PIDFILES diff --git a/nwbind.c b/nwbind.c index 652f065..23b3c45 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "07-Jul-97" +#define REVISION_DATE "22-Jul-97" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -138,7 +138,7 @@ int b_acc(uint32 obj_id, int security, int forwrite) default : errcode = -0xff; break; } - XDPRINTF((1, 0, "b_acc no rights for 0x%x to %s %s", + XDPRINTF((2, 0, "b_acc no rights for 0x%x to %s %s", act_c->object_id, acc_what, acc_typ)); return(errcode); } @@ -195,6 +195,8 @@ static int build_login_response(uint8 *responsedata, uint32 obj_id) int result; act_c->object_id = obj_id; /* actuell Object ID */ act_c->t_login = akttime; /* and login Time */ + + internal_act=1; get_guid((int*) responsedata, (int*) (responsedata+sizeof(int)), obj_id, pw_name); @@ -205,6 +207,7 @@ static int build_login_response(uint8 *responsedata, uint32 obj_id) result = 3 * sizeof(int) + 1 + (int) *(responsedata+ 3 * sizeof(int)); write_utmp(1, act_connection, act_c->pid_nwconn, &(act_c->client_adr), pw_name); + internal_act=0; return(result); } @@ -465,6 +468,7 @@ static void handle_fxx(int gelen, int func) xstrmaxcpy(obj.name, p+3, (int) *(p+2)); upstr(obj.name); xstrmaxcpy(password, p1+1, (int) *p1); + if (*p1) memset(p1+1, 0, *p1); XDPRINTF((10, 0, "LOGIN unencrypted PW NAME='%s', PASSW='%s'", obj.name, password)); if (0 == (result = find_obj_id(&obj))) { @@ -490,6 +494,7 @@ static void handle_fxx(int gelen, int func) result = nw_test_adr_time_access(obj.id, &(act_c->client_adr)); internal_act = 0; } + memset(password, 0, 50); if (!result) data_len = build_login_response(responsedata, obj.id); else @@ -857,10 +862,15 @@ static void handle_fxx(int gelen, int func) p+=2; xstrmaxcpy(obj.name, p+1, (int) *p); upstr(obj.name); + p += ((*p)+1); xstrmaxcpy(oldpassword, p+1, (int) *p); + if (*p) memset(p+1, 0, *p); + p += ((*p)+1); xstrmaxcpy(newpassword, p+1, (int) *p); + if (*p) memset(p+1, 0, *p); + if (0 == (result = find_obj_id(&obj))) { XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword, newpassword)); @@ -879,6 +889,8 @@ static void handle_fxx(int gelen, int func) internal_act = 0; } if (result < 0) completition = (uint8) -result; + memset(oldpassword, 0, 50); + memset(newpassword, 0, 50); } else { XDPRINTF((1, 0, "Change object password unencryted not enabled")); completition=0xff; @@ -1136,7 +1148,16 @@ static void handle_fxx(int gelen, int func) if (result > -1) { *(dir_name-1) = result; data_len = result+1; - } else completition = (uint8) -result; + } else { + /* + static int re=0x96; + */ + completition = (uint8) 0xd3; /* err no queue rights */ + /* + if (re == 0x96) re=0xd0; + else if (re < 0xff) ++re; + */ + } } break; @@ -1148,7 +1169,7 @@ static void handle_fxx(int gelen, int func) if (result > -1) { *(prc-1) = result; data_len = result+1; - } else completition = (uint8) -result; + } else completition = (uint8) 0xff; } break; @@ -1452,8 +1473,10 @@ int main(int argc, char *argv[]) } internal_act = 0; max_connections=get_ini_int(60); /* max_connections */ - if (max_connections < 5) + if (max_connections < 1) max_connections=MAX_CONNECTIONS; + if (max_connections < 1) + max_connections=1; connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION)); max_nw_vols=get_ini_int(61); /* max. volumes */ if (max_nw_vols < 1) @@ -1524,10 +1547,15 @@ int main(int argc, char *argv[]) got_sig = 0; } } + + /* perhaps some connections need clearing (utmp), hint from Ambrose Li */ + got_sig=max_connections+1; + while (--got_sig) + open_clear_connection(got_sig, 0, NULL); + if (ncp_fd > -1) { t_unbind(ncp_fd); t_close(ncp_fd); - XDPRINTF((2,0, "LEAVE nwbind")); if (ipx_out_fd > -1) { t_unbind(ipx_out_fd); t_close(ipx_out_fd); @@ -1535,5 +1563,6 @@ int main(int argc, char *argv[]) } sync_dbm(); xfree(connections); + XDPRINTF((2,0, "LEAVE nwbind")); return(0); } diff --git a/nwconn.c b/nwconn.c index 0b40370..0184402 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 22-Jun-97 */ +/* nwconn.c 20-Jul-97 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -77,7 +77,10 @@ typedef struct { uint8 *send_buf; /* we look from servers side * complete data buf of burst reply * file read status + file read buf + * sendbuff must be 8 byte more allocated + * than max_send_size ! */ + int max_send_size; /* send_buf size, complete Burst DATA size */ uint32 packet_sequence; /* -> packet_sequence @@ -89,7 +92,11 @@ typedef struct { struct t_unitdata ud; ipxAddr_t to_addr; - uint8 *recv_buf; /* complete data buf for burst read requests */ + uint8 *recv_buf; /* complete data buf for burst read requests + * must be 24 byte more allocated + * than max_recv_size ! + */ + int max_recv_size; /* allocated size of recv_buf */ int max_burst_data_size; /* size of BURSTDATA, max. IPX_DATA - BURSTHEADER */ @@ -270,7 +277,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); - if ( get_volume_options(volume, 1) & VOL_OPTION_REMOUNT) { + if ( get_volume_options(volume) & VOL_OPTION_REMOUNT) { U16_TO_BE16(1, xdata->removable); } else { U16_TO_BE16(0, xdata->removable); @@ -522,7 +529,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', U16_TO_BE16(fsp.fsu_bavail/sector_scale, xdata->avail_blocks); U16_TO_BE16(fsp.fsu_files, xdata->total_dirs); U16_TO_BE16(fsp.fsu_ffree, xdata->avail_dirs); - if (get_volume_options(volume, 1) & VOL_OPTION_REMOUNT) { + if (get_volume_options(volume) & VOL_OPTION_REMOUNT) { U16_TO_BE16(1, xdata->removable); } else { U16_TO_BE16(0, xdata->removable); @@ -534,19 +541,25 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', } } completition = (uint8)-result; - } else if (*p == 0x19){ /* Set Directory Information */ + } else if (*p == 0x19){ + /* Set Directory Information + * Modifies basic directory information as creation date and + * directory rights mask. DOS namespace. + */ #if 0 struct INPUT { - uint8 header[7]; /* Requestheader */ + uint8 header[7]; /* Requestheader */ uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 trustee_id[4]; /* Trustee Object ID */ - uint8 trustee_right_mask; + uint8 dir_handle; + uint8 creation_date[2]; + uint8 creation_time[2]; + uint8 owner_id[4]; + uint8 new_max_rights; uint8 pathlen; uint8 path; } *input = (struct INPUT *) (ncprequest); #endif - /* No REPLY */ + /* No REPLY */ completition = 0xfb; /* !!!!! TODO !!!! */ } else if (*p == 0x1a){ /* Get Pathname of A Volume Dir Pair */ #if 0 @@ -620,9 +633,17 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', /* remove Vol restrictions for Obj */ XDPRINTF((5, 0, "Remove vol restrictions")); return(-2); /* nwbind must do prehandling */ - } else if (*p == 0x25){ /* setting FILE INFO ??*/ + } else if (*p == 0x25){ + /* Set Entry, Set Directory File Information + * sets or changes the file or directory information to the + * values entered in 'Change Bits'. + */ + /* NO REPLY */ + /* ncopy use this call */ /* TODO !!!!!!!!!!!!!!!!!!!! */ + do_druck++; + } else if (*p == 0x26) { /* Scan file or Dir for ext trustees */ int sequenz = (int)*(p+2); /* trustee sequenz */ struct XDATA { @@ -785,9 +806,9 @@ 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){ /* ?????? */ + } else if (*p == 0x2f){ /* Fill namespace buffer */ completition = 0xfb; /* TODO: !!! */ - + /* ncopy use this call */ #if WITH_NAME_SPACE_CALLS } else if (*p == 0x30){ /* Get Name Space Directory Entry */ @@ -949,7 +970,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', { struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 reserve; /* 0x1 */ + uint8 reserve; /* 0x1, lock-flag ? */ uint8 ext_fhandle[2]; /* all zero */ uint8 fhandle[4]; /* Filehandle */ uint8 offset[4]; @@ -1466,7 +1487,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', case 0x61 : #if ENABLE_BURSTMODE - if (tells_server_version > 1) { /* > 3.11 */ + if (server_version_flags&1) { /* enable Burstmode */ /* Negotiate Buffer Size, Packetsize new ? */ int wantsize = GET_BE16((uint8*)requestdata); /* wantsize is here max. @@ -1506,7 +1527,7 @@ NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6', case 0x65 : /* Packet Burst Connection Request */ #if ENABLE_BURSTMODE - if (tells_server_version > 1) { /* > 3.11 */ + if (server_version_flags&1) { /* enable burstmode */ struct INPUT { uint8 header[7]; /* Requestheader */ uint8 connid[4]; /* RANDOM ID */ @@ -1562,12 +1583,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)); - burst_w->send_buf=xcmalloc(burst_w->max_send_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)); - burst_w->recv_buf=xcmalloc(burst_w->max_recv_size); + burst_w->recv_buf=xcmalloc(burst_w->max_recv_size+24); #if 0 U32_TO_BE32(0x1600, burst_w->sendburst->delaytime); #endif @@ -1819,12 +1849,22 @@ static int send_burst(int offset, int datasize, int flags) return(0); } +#include +static void sleep_mu(int mu) +{ + struct timeval t; + t.tv_sec = 0; + t.tv_usec = mu; + (void) select(1, NULL, NULL, NULL, &t); +} + static void handle_burst_response(uint32 offset, int size) { BURSTPACKET *sb=burst_w->sendburst; U16_TO_BE16(burst_w->burst_sequence, sb->burst_seq); U16_TO_BE16(burst_w->burst_sequence+1, sb->ack_seq); U32_TO_BE32(size, sb->burstsize); + while (size) { int sendsize=min(size, burst_w->max_burst_data_size); int flags=0; @@ -1832,10 +1872,11 @@ static void handle_burst_response(uint32 offset, int size) if (!size) flags|=0x10; /* EndOfBurst */ send_burst(offset, sendsize, flags); #if 0 - sleep_mu(1); + sleep_mu(2); #endif offset+=sendsize; } + } static void handle_burst(BURSTPACKET *bp, int len) @@ -1845,10 +1886,18 @@ static void handle_burst(BURSTPACKET *bp, int len) int burstsequence = GET_BE16(bp->burst_seq); int datasize = GET_BE16(bp->datasize); - if (datasize && !(bp->flags & 0x80)) + if (datasize && !(bp->flags & 0x80)) { + /* copy if no System Packet */ + if (datasize+burstoffset > burst_w->max_recv_size+24) { + XDPRINTF((1, 0, "recv burstpacket offs=%d+size=%d > max_recv+24=%d", + burstoffset, datasize, burst_w->max_recv_size+24)); + return; + } memcpy(burst_w->recv_buf+burstoffset, bp+1, datasize); + } if (bp->flags & 0x10) { /* last packet, now action */ + /* 0x10 = EOB flag */ struct REQ { uint8 function[4]; /* lo-hi 1=READ, 2=WRITE */ uint8 fhandle[4]; /* from open file */ @@ -1900,7 +1949,7 @@ static void handle_burst(BURSTPACKET *bp, int len) handle_burst_response(0, sizeof(struct XDATA)); } } - } else if (bp->flags & 0x80) { + } else if (bp->flags & 0x80) { /* System Flag */ int missing=GET_BE16(bp->missing); uint8 *p=(uint8*)(bp+1); burst_w->burst_sequence = burstsequence; diff --git a/nwdbm.c b/nwdbm.c index 20a288c..84719b6 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 08-Jun-97 data base for mars_nwe */ +/* nwdbm.c 24-Jul-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,8 +24,15 @@ #include "net.h" #include "nwdbm.h" #include "nwcrypt.h" +#include "dirent.h" + #ifdef LINUX -# include +# ifdef USE_GDBM +# include +# else +# include +# endif + # ifndef SHADOW_PWD # define SHADOW_PWD 0 # endif @@ -35,6 +42,12 @@ # define SHADOW_PWD 1 #endif +#ifdef USE_GDBM +# define DBM_FILE GDBM_FILE +#else +# define DBM_FILE DBM * +#endif + #if SHADOW_PWD # include #endif @@ -45,13 +58,15 @@ int tells_server_version=1; /* default 1 since 12-Jan-97 */ int password_scheme=0; 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 int sys_unixnamlen=0; /* len of unixname */ +static int sys_downshift=0; /* is SYS downshift */ + static datum key; static datum data; -static DBM *my_dbm=NULL; - +static DBM_FILE my_dbm=NULL; #define FNPROP 0 #define FNVAL 1 @@ -69,7 +84,7 @@ static char *dbm_fn[COUNT_DBM_FILES] = { }; #if DBM_REMAINS_OPEN -static DBM *my_dbms[COUNT_DBM_FILES] = { +static DBM_FILE my_dbms[COUNT_DBM_FILES] = { NULL, NULL, NULL #if COUNT_DBM_FILES > 3 , NULL @@ -80,8 +95,13 @@ static DBM *my_dbms[COUNT_DBM_FILES] = { static int x_dbminit(char *s) { char buff[256]; - sprintf(buff, "%s/%s", PATHNAME_BINDERY, s); +#ifdef USE_GDBM + (void)get_div_pathes(buff, s, 1, ".pag"); + my_dbm = gdbm_open(buff, 0, GDBM_WRCREAT, 0600, NULL); +#else + (void)get_div_pathes(buff, s, 1, NULL); my_dbm = dbm_open(buff, O_RDWR|O_CREAT, 0600); +#endif return( (my_dbm == NULL) ? -1 : 0); } @@ -103,7 +123,11 @@ static int dbmclose() { if (my_dbm != NULL) { #if !DBM_REMAINS_OPEN +# ifdef USE_GDBM + gdbm_close(my_dbm); +# else dbm_close(my_dbm); +# endif #endif my_dbm = NULL; } @@ -116,7 +140,11 @@ void sync_dbm() int k = COUNT_DBM_FILES; while (k--) { if (NULL != my_dbms[k]) { +# ifdef USE_GDBM + gdbm_close(my_dbms[k]); +# else dbm_close(my_dbms[k]); +# endif my_dbms[k] = NULL; } } @@ -124,12 +152,19 @@ void sync_dbm() } -#define firstkey() dbm_firstkey(my_dbm) -#define nextkey(key) dbm_nextkey(my_dbm) -#define delete(key) dbm_delete(my_dbm, key) -#define fetch(key) dbm_fetch(my_dbm, key) -#define store(key, content) dbm_store(my_dbm, key, content, DBM_REPLACE) - +#ifdef USE_GDBM +# define firstkey() gdbm_firstkey(my_dbm) +# define nextkey(key) gdbm_nextkey(my_dbm, key) +# define delete(key) gdbm_delete(my_dbm, key) +# define fetch(key) gdbm_fetch(my_dbm, key) +# define store(key, content) gdbm_store(my_dbm, key, content, GDBM_REPLACE) +#else +# define firstkey() dbm_firstkey(my_dbm) +# define nextkey(key) dbm_nextkey(my_dbm) +# define delete(key) dbm_delete(my_dbm, key) +# define fetch(key) dbm_fetch(my_dbm, key) +# define store(key, content) dbm_store(my_dbm, key, content, DBM_REPLACE) +#endif static int handle_iobj(int mode, NETOBJ *o) /* modes: @@ -243,7 +278,8 @@ int scan_for_obj(NETOBJ *o, uint32 last_obj_id) if (data.dptr != NULL){ NETOBJ *obj = (NETOBJ*)data.dptr; if ( ( ((int)obj->type == (int)o->type) || o->type == MAX_U16) && - name_match(obj->name, o->name)) { + name_match(obj->name, o->name) && + (b_acc(obj->id, obj->security, 0x00)== 0)) { XDPRINTF((2, 0, "found OBJ=%s, id=0x%x", obj->name, (int)obj->id)); result = 0; memcpy((char *)o, (char*)obj, sizeof(NETOBJ)); @@ -336,10 +372,14 @@ static int loc_delete_property(uint32 obj_id, return(result); } -static int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) +static int prop_delete_member(uint32 obj_id, int prop_id, int prop_security, + uint32 member_id) { - int result = 0; /* we lie insteed of -0xea; no such member */ + int result; NETVAL val; + if (0 != (result=b_acc(obj_id, prop_security, 0x11))) return(result); + else result = 0; /* we lie insteed of -0xea; no such member */ + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -401,7 +441,7 @@ static int loc_delete_obj(uint32 objid, int security) } } while (anz--) /* now try to delete obj members */ - prop_delete_member(objs[anz], props[anz], objid); + prop_delete_member(objs[anz], props[anz], 0, objid); } else result=-0xff; dbmclose(); @@ -521,7 +561,8 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id) else { data = fetch(key); prop = (NETPROP*)data.dptr; - if (data.dptr != NULL && name_match(prop->name, p->name) ) { + if (data.dptr != NULL && name_match(prop->name, p->name) + && (b_acc(obj_id, prop->security, 0x00)== 0) ) { XDPRINTF((2,0, "found PROP %s, id=0x%x", prop->name, (int) prop->id)); result = 0; memcpy(p, prop, sizeof(NETPROP)); @@ -572,11 +613,15 @@ static int loc_change_prop_security(NETPROP *p, uint32 obj_id) } -static int loc_get_prop_val(uint32 obj_id, int prop_id, int segment, - uint8 *property_value, uint8 *more_segments) +static int loc_get_prop_val(uint32 obj_id, int prop_id, int prop_security, + int segment, uint8 *property_value, uint8 *more_segments) { - int result = -0xec; /* no such Segment */ + int result; NETVAL val; + + if (0 != (result=b_acc(obj_id, prop_security, 0x10))) return(result); + else result = -0xec; /* no such Segment */ + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -600,10 +645,15 @@ static int loc_get_prop_val(uint32 obj_id, int prop_id, int segment, } -int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id) +static int prop_find_member(uint32 obj_id, int prop_id, int prop_security, + uint32 member_id) { - int result = -0xea; /* no such member */ + int result; NETVAL val; + + if (0 != (result=b_acc(obj_id, prop_security, 0x10))) return(result); + else result = -0xea; /* no such member */ + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -629,10 +679,15 @@ int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id) return(result); } -int prop_add_member(uint32 obj_id, int prop_id, uint32 member_id) +static int prop_add_member(uint32 obj_id, int prop_id, int prop_security, + uint32 member_id) { - int result = 0; /* OK */ + int result; NETVAL val; + + if (0 != (result=b_acc(obj_id, prop_security, 0x11))) return(result); + else result = 0; /* OK */ + if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; key.dptr = (char*)&val; @@ -723,7 +778,7 @@ int nw_get_prop_val_by_obj_id(uint32 obj_id, obj_id, prop.name, segment_nr)); if ((result=find_first_prop_id(&prop, obj_id))==0){ - if ((result=loc_get_prop_val(obj_id, prop.id, segment_nr, + if ((result=loc_get_prop_val(obj_id, prop.id, prop.security, segment_nr, property_value, more_segments)) == 0){ *property_flags = prop.flags; } @@ -794,7 +849,7 @@ int nw_is_obj_in_set(int object_type, if (!result) result = find_obj_id(&mobj); if (!result) - result = prop_find_member(obj.id, (int)prop.id, mobj.id); + result = prop_find_member(obj.id, (int)prop.id, prop.security, mobj.id); } return(result); } @@ -821,7 +876,7 @@ int nw_add_obj_to_set(int object_type, if (!result) result = find_obj_id(&mobj); if (!result) - result = prop_add_member(obj.id, (int)prop.id, mobj.id); + result = prop_add_member(obj.id, (int)prop.id, prop.security, mobj.id); } return(result); } @@ -848,7 +903,7 @@ int nw_delete_obj_from_set(int object_type, if (!result) result = find_obj_id(&mobj); if (!result) - result = prop_delete_member(obj.id, (int)prop.id, mobj.id); + result = prop_delete_member(obj.id, (int)prop.id, prop.security, mobj.id); } return(result); } @@ -921,7 +976,7 @@ int nw_scan_property(NETPROP *prop, last_prop_id = *last_scan; if ((result=find_prop_id(prop, obj.id, last_prop_id))==0){ *last_scan = prop->id; - if (!loc_get_prop_val(obj.id, prop->id, 1, + if (!loc_get_prop_val(obj.id, prop->id, prop->security, 1, NULL, NULL)) result = 0xff; /* Has prop Values */ } @@ -1263,15 +1318,16 @@ int nw_test_unenpasswd(uint32 obj_id, uint8 *password) xstrcpy(passwordu, password); upstr(passwordu); shuffle(s_uid, passwordu, strlen(passwordu), passwd); + memset(passwordu, 0, 100); if (!memcmp(passwd, stored_passwd, 16)) return(0); } if (NULL != (pw = nw_getpwnam(obj_id))) { int pwok = crypt_pw_ok(password, pw->pw_passwd); if (!pwok) { - uint8 passwordu[100]; xstrcpy(passwordu, password); downstr(passwordu); pwok = crypt_pw_ok(passwordu, pw->pw_passwd); + memset(passwordu, 0, 100); } return((pwok) ? 0 : -0xff); } else return(-0xff); @@ -1358,9 +1414,13 @@ int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, } static int nw_test_time_access(uint32 obj_id) -/* Routine from Matt Paley */ +/* + * Routine from Matt Paley + * and code from Mark Robson +*/ { - time_t t; + time_t t,expiry; + struct tm exptm; struct tm *tm; uint8 more_segments; uint8 property_flags; @@ -1373,8 +1433,40 @@ static int nw_test_time_access(uint32 obj_id) buff, &more_segments, &property_flags); if (result < 0) return(0); /* No time limits available */ + + /* Check if account disabled - MR */ + + if (buff[3] != 0) /* Disabled */ + { + XDPRINTF((1, 0, "No access for user %x - disabled.",obj_id)); + return (-0xdc); + } + + /* Account expires at 23:59:59 on the expiry day :) */ + if (buff[0] != 0) + { + exptm.tm_year = buff[0]; + exptm.tm_mon = buff[1]-1; + exptm.tm_mday = buff[2]; + exptm.tm_hour = 23; + exptm.tm_min = 59; + exptm.tm_sec = 59; + expiry = mktime(&exptm); + } else expiry = 0; + time(&t); tm = localtime(&t); + + if (expiry>0) /* if expiry is enabled */ + { + XDPRINTF((1,0,"user has expiry of %d but time is %d",expiry,t)); + if (t>expiry) /* has it expired ? */ + { + XDPRINTF((1, 0, "No access for user %x - expired.",obj_id)); + return (-0xdc); + } + } + half_hours = tm->tm_wday*48 + tm->tm_hour*2 + ((tm->tm_min>=30)? 1 : 0); if ((buff[14+(half_hours/8)] & (1<<(half_hours % 8))) != 0) return(0); @@ -1423,18 +1515,6 @@ int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr) return(result); } -#if 0 -int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) -/* add member to set, if member not in set */ -{ - int result = prop_find_member(obj_id, prop_id, member_id); - if (-0xea == result) - return(prop_add_member(obj_id, prop_id, member_id)); - else if (!result) result = -0xee; /* already exist */ - return(result); -} -#endif - static int nw_new_add_prop_member(uint32 obj_id, char *propname, int propflags, int propsecurity, uint32 member_id) @@ -1447,24 +1527,45 @@ static int nw_new_add_prop_member(uint32 obj_id, char *propname, prop.security = (uint8) propsecurity; result = nw_create_obj_prop(obj_id, &prop); if (!result || result == -0xed) { /* created or exists */ - if (-0xea == (result=prop_find_member(obj_id, prop.id, member_id))) - return(prop_add_member(obj_id, prop.id, member_id)); + if (-0xea == (result=prop_find_member(obj_id, prop.id, prop.security, member_id))) + return(prop_add_member(obj_id, prop.id, prop.security, member_id)); else if (!result) result = -0xee; /* already exist */ } return(result); } +static int xmkdir(char *unixname, int mode) +{ + char *p=unixname; + while (NULL != (p=strchr(p+1, '/'))) { + *p = '\0'; + if (!mkdir(unixname, mode)) + chmod(unixname, mode); + *p='/'; + } + if (!mkdir(unixname, mode)) { + chmod(unixname, mode); + return(0); + } + return(-1); +} + static void create_nw_db(char *fn, int always) { char fname[200]; struct stat stbuff; - sprintf(fname, "%s/%s.dir", PATHNAME_BINDERY, fn); + (void)get_div_pathes(fname, fn, 1, ".dir"); + if (stat(fname, &stbuff)){ + (void)get_div_pathes(fname, NULL, 1, NULL); + xmkdir(fname, 0700); + (void)get_div_pathes(fname, fn, 1, ".dir"); + } if (always || stat(fname, &stbuff)){ int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); } chmod(fname, 0600); - sprintf(fname, "%s/%s.pag", PATHNAME_BINDERY, fn); + (void)get_div_pathes(fname, fn, 1, ".pag"); if (always || stat(fname, &stbuff)){ int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); @@ -1481,12 +1582,12 @@ static void add_pr_queue(uint32 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, - "Q_DIRECTORY", P_FL_ITEM, 0x33, + "Q_DIRECTORY", P_FL_ITEM, 0x31, q_directory, strlen(q_directory), 1); /* this is mars_nwe own property to handle the print job !!! */ nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 , - "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33, + "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); @@ -1575,21 +1676,6 @@ static void add_group(char *name, char *unname, char *password) (char*)unname, strlen(unname), 1); } -static int xmkdir(char *unixname, int mode) -{ - char *p=unixname; - while (NULL != (p=strchr(p+1, '/'))) { - *p = '\0'; - if (!mkdir(unixname, mode)) - chmod(unixname, mode); - *p='/'; - } - if (!mkdir(unixname, mode)) { - chmod(unixname, mode); - return(0); - } - return(-1); -} static int get_sys_unixname(uint8 *unixname, uint8 *sysname, uint8 *sysentry) { @@ -1643,6 +1729,7 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags, if (xmkdir(unixname, permiss)< 0) errorp(1, "mkdir error", "fname='%s'", unixname); else { + chmod(unixname, permiss); if (uid >-1 && gid > -1) chown(unixname, uid, gid); XDPRINTF((1, 0, "Created dir '%s'", unixname)); @@ -1661,6 +1748,41 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags, return(pp); } +static void correct_user_dirs(uint32 objid, int uid, int gid) +{ + uint8 fndir[512]; + uint8 *p = fndir+sys_unixnamlen; + uint8 *pp; + 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) + upstr(p); + (void)mkdir(fndir, 0733); + (void)chmod(fndir, 0733); + (void)chown(fndir, uid, gid); + + if ((f=opendir(fndir)) != (DIR*)NULL) { + struct dirent* dirbuff; + *pp='/'; + while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ + if (dirbuff->d_ino) { + uint8 *name=(uint8*)(dirbuff->d_name); + if (name[0] != '.' && name[1] != '.' && name[1] != '\0') { + strcpy(pp+1, name); + (void)chown(fndir, uid, gid); + } + } + } + *pp='\0'; + closedir(f); + } +} + void test_ins_unx_user(uint32 id) { NETOBJ obj; @@ -1671,8 +1793,10 @@ void test_ins_unx_user(uint32 id) xstrcpy(unxname, obj.name); downstr(unxname); pw = getpwnam(unxname); - if (NULL != pw && pw->pw_uid) /* only non root user */ - add_user_2_unx(id, unxname); + 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); + } } } @@ -1785,6 +1909,8 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) add_user_g((12 == what) ? su_id : 0L, ge_id, nname, uname, password, 0, flags, set_flags); } + memset(password, 0, sizeof(password)); + memset(buff, 0, sizeof(buff)); } else if (15 == what) { char buf[100]; int anz=sscanf((char*)buff, "%s %s", buf, auto_ins_passwd); @@ -1860,6 +1986,8 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) } endpwent(); } + memset(auto_ins_passwd, 0, sizeof(auto_ins_passwd)); + if (*sysentry) { int result = 0; if (make_tests) { @@ -1876,6 +2004,10 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) 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"); diff --git a/nwdbm.h b/nwdbm.h index f59eb06..1dd7a26 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -101,9 +101,6 @@ extern int nw_change_obj_security(NETOBJ *o, int newsecurity); extern int nw_get_obj(NETOBJ *o); -extern int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id); -extern int prop_add_member(uint32 obj_id, int prop_id, uint32 member_id); - extern int nw_get_prop_val_by_obj_id(uint32 obj_id, int segment_nr, uint8 *prop_name, int prop_namlen, diff --git a/nwfile.c b/nwfile.c index 9bda323..fe525f2 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 02-Jun-97 */ +/* nwfile.c 25-Jul-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include #include "nwvolume.h" +#include "nwshare.h" #include "nwfile.h" #include "connect.h" #include "nwconn.h" @@ -40,13 +41,13 @@ void sig_bus_mmap(int rsig) static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN]; #define HOFFS 0 -static int anz_fhandles=0; +static int count_fhandles=0; static int new_file_handle(uint8 *unixname, int task) { int fhandle = HOFFS -1; FILE_HANDLE *fh=NULL; - while (++fhandle < anz_fhandles) { + while (++fhandle < count_fhandles) { fh=&(file_handles[fhandle]); if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */ fhandle++; @@ -54,9 +55,9 @@ static int new_file_handle(uint8 *unixname, int task) } else fh=NULL; } if (fh == NULL) { - if (anz_fhandles < MAX_FILE_HANDLES_CONN) { - fh=&(file_handles[anz_fhandles]); - fhandle = ++anz_fhandles; + if (count_fhandles < MAX_FILE_HANDLES_CONN) { + fh=&(file_handles[count_fhandles]); + fhandle = ++count_fhandles; } else { XDPRINTF((1, 0, "No more free file handles")); return(0); /* no free handle anymore */ @@ -67,11 +68,12 @@ static int new_file_handle(uint8 *unixname, int task) fh->fd = -2; fh->offd = 0L; fh->tmodi = 0L; + fh->st_ino = 0; strcpy((char*)fh->fname, (char*)unixname); fh->fh_flags = 0; fh->f = NULL; - XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s", - fhandle, anz_fhandles, unixname)); + 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; @@ -97,7 +99,7 @@ static int free_file_handle(int fhandle) ipx_io.fd_w=-1; } - if (fhandle > HOFFS && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE_COMMAND) { @@ -110,6 +112,8 @@ static int free_file_handle(int fhandle) fh->size_mmap = 0; } close(fh->fd); + if (fh->st_ino) + share_file(fh->st_dev, fh->st_ino, 0); } if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags) && !(FH_IS_READONLY & fh->fh_flags) ) { @@ -121,17 +125,15 @@ static int free_file_handle(int fhandle) } } fh->fd = -1; - if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) { - /* was last */ - anz_fhandles--; - while (anz_fhandles > HOFFS && file_handles[anz_fhandles-1].fd == -1 - && !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) - anz_fhandles--; + while (count_fhandles > fhandle + && file_handles[count_fhandles-1].fd == -1 + && !(file_handles[count_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) { + count_fhandles--; } result=0; } - XDPRINTF((5, 0, "free_file_handle=%d, anz_fhandles=%d, result=%d", - fhandle, anz_fhandles, result)); + XDPRINTF((5, 0, "free_file_handle=%d, count_fhandles=%d, result=%d", + fhandle, count_fhandles, result)); return(result); /* wrong filehandle */ } @@ -143,12 +145,12 @@ void init_file_module(int task) { int k = HOFFS; if (task < 0) { - while (k++ < anz_fhandles) + while (k++ < count_fhandles) free_file_handle(k); - anz_fhandles = HOFFS; + count_fhandles = HOFFS; } else { /* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */ - while (k++ < anz_fhandles) { + while (k++ < count_fhandles) { FILE_HANDLE *fh=&(file_handles[k-1]); if (fh->task == task) { free_file_handle(k); @@ -212,7 +214,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, if (fhandle > HOFFS){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); int completition = 0; /* first ok */ - int voloptions = get_volume_options(volume, 1); + int voloptions = get_volume_options(volume); int acc = (!stat(fh->fname, stbuff)) ? get_real_access(stbuff) : -1; @@ -241,6 +243,13 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, completition = (creatmode) ? -0x84 : -0x94; } else if (!(acc & R_OK) && !(creatmode & 0x8) ) completition = -0x93; + + if ((!completition) && !S_ISFIFO(stbuff->st_mode) && dowrite){ + /* is this file already opened write deny by other process */ + if (-1 == share_file(stbuff->st_dev, stbuff->st_ino, 0x12|0x8)) + completition=-0x80; + } + } else if (acc & X_OK) { /* special Handling for PIPE commands */ if (!(acc & W_OK)) { @@ -367,38 +376,35 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } if (fh->fd > -1) { + if (did_grpchange) { + xsetegid(act_gid); + did_grpchange=0; + } if (!(fh->fh_flags & FH_IS_PIPE)) { /* Not a PIPE */ - if ((access & 0x4) || (access & 0x8)) { - /* we use file sharing */ - struct flock flockd; - int result = (access & 0x4) ? 1 : 0; /* here for writelock */ -#if 0 - if (result != dowrite) { - XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes openmode=%s, file=%s", - access, (dowrite) ? "W" : "R", fh->fname)); - result = dowrite; - } -#else - if ((!dowrite) && result) { - XDPRINTF((1,0, "OpenFile:Share(access)=0x%x clashes R-open file=%s", - access, fh->fname)); - result = dowrite; - } -#endif - flockd.l_type = (result) ? F_WRLCK : F_RDLCK; - flockd.l_whence = SEEK_SET; - flockd.l_start = 0; - flockd.l_len = 0; - result = fcntl(fh->fd, F_SETLK, &flockd); + int result=0; + fh->st_dev=stbuff->st_dev; + fh->st_ino=stbuff->st_ino; + if ( (!result) && ((access & 0x4) || (access & 0x8)) ) { + if (access & 0x4) /* deny read */ + result=share_file(stbuff->st_dev, stbuff->st_ino, 0x5); + if ((access & 0x8) && !result) + result=share_file(stbuff->st_dev, stbuff->st_ino, 0x2); XDPRINTF(((result==-1)?2:5, 0, "open shared lock:result=%d,fn='%s'", result, fh->fname)); - if (result == -1) { - close(fh->fd); - fh->fd = -1; - completition=-0xfe; + } else { + result=share_file(stbuff->st_dev, stbuff->st_ino, 1); + if (result==-1) { + XDPRINTF((2, 0, "open share failed,fn='%s'", fh->fname)); } } + if (result==-1) { + close(fh->fd); + fh->fd = -1; + completition = -0x80; + /* 0.99.pl0 changed -0xfe -> -0x80 */ + } + if (use_mmap && fh->fd > -1 && !dowrite) { fh->size_mmap = fh->offd=lseek(fh->fd, 0L, SEEK_END); if (fh->size_mmap > 0) { @@ -416,14 +422,14 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } } if (fh->fd > -1) { + if (did_grpchange) + xsetegid(act_gid); if (!dowrite) fh->fh_flags |= FH_OPENED_RO; if (voloptions & VOL_OPTION_READONLY) fh->fh_flags |= FH_IS_READONLY; if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; - if (did_grpchange) - xsetegid(act_gid); goto file_creat_open_ret; } } /* else (note pipecommand) */ @@ -450,22 +456,33 @@ file_creat_open_ret: int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles) ) { + if (fhandle > HOFFS && (--fhandle < count_fhandles) ) { FILE_HANDLE *fh=&(file_handles[fhandle]); - if (fh->fd > -1) { - if (!(fh->fh_flags & FH_IS_READONLY)) { - fh->tmodi = nw_2_un_time(datum, zeit); - return(0); - } else return(-0x8c); - } else if (fh->fd == -3) return(0); + if (fh->fd == -3 || (fh->fh_flags & FH_IS_PIPE)) return(0); + if (!(fh->fh_flags & FH_IS_READONLY)) { + fh->tmodi = nw_2_un_time(datum, zeit); + if (fh->fd == -1) { /* already closed */ +#if 0 + /* don't know whether we should do it in this way */ + struct utimbuf ut; + if (!*(fh->fname)) + return(-0x88); /* wrong filehandle */ + ut.actime = ut.modtime = fh->tmodi; + utime(fh->fname, &ut); +#else + return(-0x88); /* wrong filehandle */ +#endif + } + return(0); + } else return(-0x8c); /* no modify privileges */ } return(-0x88); /* wrong filehandle */ } int nw_close_file(int fhandle, int reset_reuse) { - XDPRINTF((5, 0, "nw_close_file handle=%d, anz_fhandles", - fhandle, anz_fhandles)); + XDPRINTF((5, 0, "nw_close_file handle=%d, count_fhandles", + fhandle, count_fhandles)); MDEBUG(D_FH_OPEN, { char fname[200]; @@ -473,7 +490,7 @@ int nw_close_file(int fhandle, int reset_reuse) xdprintf(1,0,"nw_close_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r); }) - if (fhandle > HOFFS && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE); if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) { @@ -492,6 +509,8 @@ int nw_close_file(int fhandle, int reset_reuse) fh->size_mmap = 0; } result=close(fh->fd); + if (fh->st_ino) + share_file(fh->st_dev, fh->st_ino, 0); } fh->fd = -1; if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE) @@ -522,12 +541,17 @@ int nw_commit_file(int fhandle) int r=fd_2_fname(fhandle, fname, sizeof(fname)); xdprintf(1,0,"nw_commit_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r); }) - if (fhandle > HOFFS && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) { if (!(fh->fh_flags & FH_IS_READONLY)) { int result=0; if (!(fh->fh_flags & FH_IS_PIPE) && fh->fd > -1) { +#if 0 + /* 0.99.pl0 + * this is not allowed because lockings will be removed + * hint from: Przemyslaw Czerpak + */ int fd=dup(fh->fd); if (fd > -1) { if (!close(fh->fd)) { @@ -542,6 +566,13 @@ int nw_commit_file(int fhandle) result=-0x8c; close(fd); } +#else + if (fh->tmodi > 0L) { + struct utimbuf ut; + ut.actime = ut.modtime = fh->tmodi; + utime(fh->fname, &ut); + } +#endif } return(result); } else @@ -554,7 +585,7 @@ int nw_commit_file(int fhandle) uint8 *file_get_unix_name(int fhandle) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { return((uint8*)file_handles[fhandle].fname); } return(NULL); @@ -575,7 +606,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite) int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fh_flags & FH_IS_PIPE_COMMAND) open_pipe_command(fh, 0); @@ -637,7 +668,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) int nw_seek_file(int fhandle, int modus) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ @@ -659,7 +690,7 @@ int nw_seek_file(int fhandle, int modus) int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fh_flags & FH_IS_PIPE_COMMAND) open_pipe_command(fh, 1); @@ -706,8 +737,8 @@ int nw_server_copy(int qfhandle, uint32 qoffset, int zfhandle, uint32 zoffset, uint32 size) { - if (qfhandle > HOFFS && (--qfhandle < anz_fhandles) - && zfhandle > HOFFS && (--zfhandle < anz_fhandles) ) { + if (qfhandle > HOFFS && (--qfhandle < count_fhandles) + && zfhandle > HOFFS && (--zfhandle < count_fhandles) ) { FILE_HANDLE *fhq=&(file_handles[qfhandle]); FILE_HANDLE *fhz=&(file_handles[zfhandle]); int retsize = -1; @@ -745,7 +776,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset, int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock) { int result=-0x88; /* wrong filehandle */ - if (fhandle > HOFFS && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { struct flock flockd; @@ -767,7 +798,7 @@ int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock) */ flockd.l_start = (offset & 0x7fffffff); #endif - + if (size == MAX_U32) { /* This is only a guess, but a size of 0xffffffff means to lock * the rest of the file, starting from the offset, to do this with @@ -778,12 +809,13 @@ int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock) flockd.l_len = 0; } else flockd.l_len = (size & 0x7fffffff); - + result = fcntl(fh->fd, F_SETLK, &flockd); XDPRINTF((2, 0, "nw_%s_datei result=%d, fh=%d, offset=%d, size=%d", (do_lock) ? "lock" : "unlock", result, fhandle, offset, size)); if (result) - result= (do_lock) ? -0xfd : -0xff; + result= (do_lock) ? -0xfe : -0xff; + /* 0.99.pl0: changed -0xfd -> -0xfe, hint from Przemyslaw Czerpak */ } else if (fh->fd == -3) result=0; } leave: @@ -800,7 +832,7 @@ leave: int fd_2_fname(int fhandle, char *buf, int bufsize) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); strmaxcpy(buf, fh->fname, bufsize-1); return(0); @@ -812,18 +844,37 @@ int fd_2_fname(int fhandle, char *buf, int bufsize) FILE_HANDLE *fd_2_fh(int fhandle) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) + if (fhandle > HOFFS && (--fhandle < count_fhandles)) return(&(file_handles[fhandle])); return(NULL); } int get_nwfd(int fhandle) { - if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < count_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); return(fh ? fh->fd : -1); } return(-1); } +int nw_unlink(int volume, char *name) +{ + struct stat stbuff; + if (get_volume_options(volume) & VOL_OPTION_IS_PIPE) + return(0); /* don't delete 'pipe commands' */ + else if (get_volume_options(volume) & VOL_OPTION_READONLY) + return(-0x8a); /* don't delete 'readonly' */ + if (stat(name, &stbuff)) + return(-0x9c); /* wrong path */ + + if ( -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x12|0x8) + || ( !(entry8_flags&0x10) && + -1 == share_file(stbuff.st_dev, stbuff.st_ino, 0x11|0x4)) ) + return(-0x8a); /* NO Delete Privileges */ + if (!unlink(name)) + return(0); + return(-0x8a); /* NO Delete Privileges */ +} + diff --git a/nwfile.h b/nwfile.h index 57380e7..0dd9ffc 100644 --- a/nwfile.h +++ b/nwfile.h @@ -1,4 +1,4 @@ -/* nwfile.h 02-Jun-97 */ +/* nwfile.h 21-Jul-97 */ #ifndef _NWFILE_H_ #define _NWFILE_H_ #include "nwqueue.h" @@ -14,6 +14,8 @@ typedef struct { int fh_flags; /* 2 = PIPE */ /* 4 = don't reuse after close */ /* 0x20 = readonly */ + int st_dev; /* device */ + int st_ino; /* inode */ char fname[256]; /* UNIX filename */ } FILE_HANDLE; @@ -53,4 +55,6 @@ extern int fd_2_fname(int fhandle, char *buf, int bufsize); extern FILE_HANDLE *fd_2_fh(int fhandle); extern int get_nwfd(int fhandle); +extern int nw_unlink(int volume, char *name); + #endif diff --git a/nwroute.c b/nwroute.c index d188c41..823daf9 100644 --- a/nwroute.c +++ b/nwroute.c @@ -1,4 +1,4 @@ -/* nwroute.c 02-Jun-97 */ +/* nwroute.c 17-Jul-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -44,6 +44,12 @@ static int anz_servers=0; static int max_nw_servers=0; static NW_SERVERS **nw_servers=NULL; +#define NEEDS_UPDATE_SAP 1 +#define NEEDS_UPDATE_SAP_QUERY 2 +#define NEEDS_UPDATE_RIP 4 +#define NEEDS_UPDATE_RIP_NET 8 +#define NEEDS_UPDATE_ALL (8|4|2|1) + static void insert_delete_net(uint32 destnet, uint32 rnet, /* routernet */ uint8 *rnode, /* routernode */ @@ -178,6 +184,19 @@ static NW_NET_DEVICE *find_device_by_net(uint32 net) return(NULL); } +int activate_slow_net(uint32 net) +{ + NW_NET_DEVICE *nd=find_device_by_net(net); + if (nd && nd->ticks > 6) { /* if 'slow net' */ + if (acttime_stamp > nd->updated_time + 600) { + nd->needs_update=NEEDS_UPDATE_ALL; + nd->updated_time=acttime_stamp; + return(1); + } + } + return(0); +} + void insert_delete_server(uint8 *name, /* Server Name */ int styp, /* Server Typ */ ipxAddr_t *addr, /* Server Addr */ @@ -299,7 +318,7 @@ static void ins_rip_buff(uint32 net, uint16 hops, uint16 ticks) if (rentries >= max_rip_entries) { int new_rip_entries=max_rip_entries+5; uint8 *new_ripbuf=xcmalloc(2 + new_rip_entries*8); - if (max_rip_entries) + if (max_rip_entries) memcpy(new_ripbuf, rip_buff, 2 + max_rip_entries*8); xfree(rip_buff); rip_buff=new_ripbuf; @@ -390,12 +409,16 @@ static void send_rip_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ /* mode=2, shutdown */ +/* mode=4, only to needs update*/ { int k=-1; while (++k < count_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->is_up && (nd->ticks < 7 || mode)) { + if (mode == 4 && !(nd->needs_update&NEEDS_UPDATE_RIP)) continue; + if (nd->is_up && (nd->ticks < 7 + || mode || (nd->needs_update&NEEDS_UPDATE_RIP) )) { /* isdn devices should not get RIP broadcasts everytime */ + nd->needs_update&=~NEEDS_UPDATE_RIP; init_rip_buff(nd->net, (mode == 2) ? 1 : 0); build_rip_buff(MAX_U32); send_rip_buff(NULL); @@ -408,7 +431,10 @@ void rip_for_net(uint32 net) int k=-1; while (++k < count_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->is_up && nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */ + if (nd->is_up && (nd->ticks < 7 + || (nd->needs_update&NEEDS_UPDATE_RIP_NET) ) ) { + /* isdn devices should not get RIP broadcasts everytime */ + nd->needs_update&=~NEEDS_UPDATE_RIP_NET; init_rip_buff(nd->net, 10); ins_rip_buff(net, MAX_U16, MAX_U16); send_rip_buff(NULL); @@ -488,36 +514,26 @@ void send_server_response(int respond_typ, int styp, ipxAddr_t *to_addr) /* respond_typ 2 = general, 4 = nearest service respond */ { - int j=-1; - int ticks=99; - int hops=15; - int entry = -1; - - int to_internal = (!no_internal) - && (GET_BE32(to_addr->net) == internal_net) - && (GET_BE16(to_addr->sock) != SOCK_SAP); - - while (++j < anz_servers) { + int j = -1; + int ticks = 99; + int hops = 15; + int entry = -1; + while (ticks && ++j < anz_servers) { NW_SERVERS *nw=nw_servers[j]; if (nw->typ == styp && nw->name && *(nw->name)) { int xticks=999; if (nw->net != internal_net) { NW_NET_DEVICE *nd=find_netdevice(nw->net); if (nd) xticks = nd->ticks; - if (to_internal) - send_sap_to_addr(j, nw->hops+1, xticks, respond_typ, to_addr); } else xticks = 0; if (xticks < ticks || (xticks == ticks && nw->hops <= hops)) { - ticks = xticks; + ticks = xticks; hops = nw->hops; entry = j; } } } -#if 0 /* removed: 16-May-96 */ - if (!to_internal) -#endif - send_sap_to_addr(entry, hops+1, ticks, respond_typ, to_addr); + send_sap_to_addr(entry, hops+1, ticks, respond_typ, to_addr); } @@ -539,23 +555,37 @@ static void send_sip_to_net(uint32 nd_net, int nd_ticks, int mode) mode, nd_net, nw->name)); continue; } + +#ifdef CONFIG_C_LEASING + if (nd_ticks > 6 + && nw->typ != 0x0004 + && nw->typ != 0x0107 + && nw->typ != 0x023f + && nw->typ != 0x027b + && nw->typ != 0x044c) continue; +#endif + send_sap_to_addr(j, (mode == 2) ? 16 : nw->hops+1, nd_ticks, 2, /* General */ &wild); - } + } /* while */ } static void send_sap_broadcast(int mode) /* mode=0, standard broadcast */ /* mode=1, first trie */ /* mode=2, shutdown */ +/* mode=4, only update*/ { int k=-1; while (++k < count_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->is_up && (nd->ticks < 7 || mode)) { + if (mode == 4 && !(nd->needs_update&NEEDS_UPDATE_SAP)) continue; + if (nd->is_up && (nd->ticks < 7 || + (nd->needs_update&NEEDS_UPDATE_SAP) || mode)) { /* isdn devices should not get SAP broadcasts everytime */ + nd->needs_update &= ~NEEDS_UPDATE_SAP; send_sip_to_net(nd->net, nd->ticks, mode); } } @@ -671,6 +701,7 @@ void send_sap_rip_broadcast(int mode) /* mode=1, first trie */ /* mode=2, shutdown */ /* mode=3, update routes */ +/* mode=4, resend to net */ { static int flipflop=1; int force_print_routes=(mode == 1) ? 1 : 0; @@ -699,8 +730,8 @@ static int flipflop=1; print_routing_info(force_print_routes); /* every second time */ } -static void query_sap_on_net(uint32 net) -/* searches for the next server on this network */ +static void sap_find_nearest_server(uint32 net) +/* searches for the nearest server on network net */ { SQP sqp; ipxAddr_t wild; @@ -708,24 +739,27 @@ static void query_sap_on_net(uint32 net) memset(wild.node, 0xFF, IPX_NODE_SIZE); U32_TO_BE32(net, wild.net); U16_TO_BE16(SOCK_SAP, wild.sock); - U16_TO_BE16(3, sqp.query_type); - U16_TO_BE16(4, sqp.server_type); + U16_TO_BE16(3, sqp.query_type); /* 3 nearest Server Query */ + U16_TO_BE16(4, sqp.server_type); /* file server */ send_ipx_data(sockfd[SAP_SLOT], 17, sizeof(SQP), (char*)&sqp, &wild, "SERVER Query"); } - + void get_servers(void) { int k=-1; while (++k < count_net_devices) { NW_NET_DEVICE *nd=net_devices[k]; - if (nd->is_up && nd->ticks < 7) - query_sap_on_net(nd->net); /* only fast routes */ + if (nd->is_up && (nd->ticks < 7 + || nd->needs_update&NEEDS_UPDATE_SAP_QUERY)){ + nd->needs_update &= ~NEEDS_UPDATE_SAP_QUERY; + sap_find_nearest_server(nd->net); + } } - if (!count_net_devices) query_sap_on_net(internal_net); + if (!count_net_devices) sap_find_nearest_server(internal_net); } - + int dont_send_wdog(ipxAddr_t *addr) /* returns != 0 if ticks are to high for wdogs */ { @@ -742,7 +776,7 @@ void realloc_net_devices(void) int new_max_netd=max_net_devices+2; NW_NET_DEVICE **new_nd=(NW_NET_DEVICE**) xcmalloc(new_max_netd*sizeof(NW_NET_DEVICE*)); - if (max_net_devices) + if (max_net_devices) memcpy(new_nd, net_devices, max_net_devices*sizeof(NW_NET_DEVICE*)); xfree(net_devices); net_devices=new_nd; @@ -768,7 +802,7 @@ int test_ins_device_net(uint32 rnet) foundfree = k; } else if (nd->net == rnet) return(0); } - + if ((rnetframe=get_interface_frame_name(rnetdevname, rnet)) < 0) return(0); @@ -809,7 +843,7 @@ int test_ins_device_net(uint32 rnet) int matched=0; k=-1; - if (count_net_devices >= max_net_devices) + if (count_net_devices >= max_net_devices) realloc_net_devices(); while (++k < count_net_devices) { @@ -837,6 +871,7 @@ int test_ins_device_net(uint32 rnet) nd->frame = rnetframe; new_str(nd->devname, rnetdevname); nd->is_up = 2; + nd->needs_update=NEEDS_UPDATE_ALL; /* now perhaps i must delete an existing route over */ /* another device */ @@ -901,10 +936,14 @@ static int look_for_interfaces(void) int j; find_diffs++; nd->is_up = 0; /* this will be put DOWN */ + XDPRINTF((1,0,"Device %s net=0x%x removed", + nd->devname ? nd->devname : "?", nd->net)); for (j=0; j < anz_routes; j++){ NW_ROUTES *nr=nw_routes[j]; - if (nr && nr->rnet == nd->net) + if (nr && nr->rnet == nd->net) { nr->net = 0L; /* remove route */ + XDPRINTF((1,0,"Route to net=0x%x removed", nr->net)); + } } if (nd->wildmask & 1) new_str(nd->devname, "*"); diff --git a/nwroute1.c b/nwroute1.c index fa8f7fc..f025964 100644 --- a/nwroute1.c +++ b/nwroute1.c @@ -1,4 +1,4 @@ -/* nwroute1.c 02-Jun-97 */ +/* nwroute1.c 17-Jul-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -31,6 +31,11 @@ static int anz_servers=0; static int max_nw_servers=0; static NW_SERVERS **nw_servers=NULL; +int activate_slow_net(uint32 net) +{ + ;; /* dummy */ +} + void insert_delete_server(uint8 *name, /* Server Name */ int styp, /* Server Typ */ ipxAddr_t *addr, /* Server Addr */ @@ -95,7 +100,7 @@ void insert_delete_server(uint8 *name, /* Server Name */ void rip_for_net(uint32 net) { -; + ;; /* dummy */ } void handle_rip(int fd, int ipx_pack_typ, diff --git a/nwserv.c b/nwserv.c index 0fb2fc6..8378dcd 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,4 +1,4 @@ -/* nwserv.c 02-Jun-97 */ +/* nwserv.c 17-Jul-97 */ /* MAIN Prog for NWSERV + NWROUTED */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -35,6 +35,9 @@ int print_route_tac = 0; /* every x broadcasts print it */ int print_route_mode = 0; /* append */ char *pr_route_info_fn = NULL; /* filename */ int wdogs_till_tics = 0; /* send wdogs to all */ +time_t acttime_stamp = 0; /* actual received time (second) */ + + /* <========== DEVICES ==========> */ int count_net_devices=0; int max_net_devices=0; @@ -110,7 +113,6 @@ static int sock_nwbind = -1; static int fd_nwbind_in = -1; /* ctrl-pipe in from nnwbind */ -static time_t akttime_stamp = 0; static int broadmillisecs = 2000; /* 2 sec */ static time_t server_down_stamp = 0; static int server_goes_down_secs = 10; @@ -430,7 +432,7 @@ static void insert_wdog_conn(int conn, ipxAddr_t *adr) memset(c, 0, sizeof(CONNECTION)); } c=&(connections[conn-1]); - c->last_time = akttime_stamp; + c->last_time = acttime_stamp; c->counter = 0; if (NULL != adr) memcpy(&(c->addr), adr, sizeof(ipxAddr_t)); } @@ -452,7 +454,7 @@ static void modify_wdog_conn(int conn, int mode) break; default : c->counter = 0; /* reset */ - c->last_time = akttime_stamp; + c->last_time = acttime_stamp; break; } /* switch */ } else if (mode == 99) { /* remove */ @@ -474,7 +476,7 @@ static void send_wdogs() while (k--) { CONNECTION *c = &(connections[k]); if (c->last_time) { - time_t t_diff = akttime_stamp - c->last_time; + time_t t_diff = acttime_stamp - c->last_time; if ( (c->counter && t_diff > 50) || t_diff > WDOG_TRIE_AFTER_SEC) { /* max. 5 minutes */ if (c->counter > MAX_WDOG_TRIES) { @@ -483,7 +485,7 @@ static void send_wdogs() write_to_ncpserv(0x5555, k+1, NULL, 0); } else { ipxAddr_t adr; - c->last_time = akttime_stamp; + c->last_time = acttime_stamp; memcpy(&adr, &(c->addr), sizeof(ipxAddr_t)); U16_TO_BE16(GET_BE16(adr.sock)+1, adr.sock); send_wdog_packet(&adr, k+1, '?'); @@ -532,6 +534,7 @@ static void handle_sap(int fd, { int query_type = GET_BE16(ipxdata->sqp.query_type); int server_type = GET_BE16(ipxdata->sqp.server_type); + int flag=0; if (query_type == 3) { XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d from %s", @@ -569,6 +572,7 @@ static void handle_sap(int fd, /* if (hops < 16) hops++; */ XDPRINTF((2,0, "TYP=%2d,hops=%2d, Addr=%s, Name=%s", type, hops, visable_ipx_adr(ad), name)); + if (handle_all_sap_typs || type == 4) { /* from Fileserver */ if (16 == hops) { /* shutdown */ @@ -577,13 +581,23 @@ static void handle_sap(int fd, } else { get_server_data((char*)name, ad, from_addr); insert_delete_server(name, type, ad, from_addr, hops, 0, 0); + if (type == 4) flag=1; } } + p+=sizeof(SAPS); } /* while */ } else { XDPRINTF((1,0, "UNKNOWN SAP query %x, server %x", query_type, server_type)); } + +#if INTERNAL_RIP_SAP + if (flag) { + uint32 from_net=GET_BE32(from_addr->net); + if (activate_slow_net(from_net)) + send_sap_rip_broadcast(4); + } +#endif } /* @@ -944,7 +958,7 @@ static void get_ini(int full) #if !IN_NWROUTED case 60 : if (full) { /* connections */ max_connections=atoi(inhalt); - if (max_connections < 5) + if (max_connections < 1) max_connections=MAX_CONNECTIONS; } break; @@ -1137,7 +1151,7 @@ static void down_server(void) sleep(1); fprintf(stderr, "\007\n"); broadmillisecs = 100; - server_down_stamp = akttime_stamp; + server_down_stamp = acttime_stamp; send_down_broadcast(); } } @@ -1265,6 +1279,8 @@ int main(int argc, char **argv) set_sigs(0); get_ini(1); #if !IN_NWROUTED + if (max_connections < 1) + max_connections=1; connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION)); #endif j=-1; @@ -1324,8 +1340,8 @@ int main(int argc, char **argv) int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs); #if !IN_NWROUTED int call_wdog=0; -#endif - time(&akttime_stamp); +#endif + time(&acttime_stamp); #if !IN_NWROUTED if (fl_got_sigchld) { int stat_loc=-1; @@ -1447,11 +1463,11 @@ int main(int argc, char **argv) } if (server_down_stamp) { - if (akttime_stamp - server_down_stamp > server_goes_down_secs) + if (acttime_stamp - server_down_stamp > server_goes_down_secs) server_is_down++; } else { int bsecs = broadmillisecs / 1000; - int difftime = akttime_stamp - broadtime; + int difftime = acttime_stamp - broadtime; if (difftime > bsecs) { send_sap_rip_broadcast((bsecs < 3) ? 1 : 0); /* firsttime broadcast */ if (bsecs < server_broadcast_secs) { @@ -1465,7 +1481,7 @@ int main(int argc, char **argv) #if !IN_NWROUTED send_wdogs(); #endif - broadtime = akttime_stamp; + broadtime = acttime_stamp; } else { #if !IN_NWROUTED if (call_wdog) send_wdogs(1); diff --git a/nwserv.h b/nwserv.h index 933a0b2..5bdd2e4 100644 --- a/nwserv.h +++ b/nwserv.h @@ -1,4 +1,4 @@ -/* nwserv.h 10-Apr-97 */ +/* nwserv.h 17-Jul-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -26,14 +26,17 @@ extern int print_route_tac; /* every x broadcasts print it */ extern int print_route_mode; /* append */ extern char *pr_route_info_fn; /* filename */ extern int wdogs_till_tics; +extern time_t acttime_stamp; typedef struct { - char *devname; /* "eth0" or "isdnX" or ?? */ - int frame; /* frametyp */ - int ticks; /* ether:ticks=1, isdn:ticks=7 */ - uint32 net; /* NETWORK NUMBER */ - int is_up; /* Is this device up ? */ - int wildmask; /* wildmask, 1=name, 2=frame, 4=net */ + char *devname; /* "eth0" or "isdnX" or ?? */ + int frame; /* frametyp */ + int ticks; /* ether:ticks=1, isdn:ticks=7 */ + uint32 net; /* NETWORK NUMBER */ + int is_up; /* Is this device up ? */ + int wildmask; /* wildmask, 1=name, 2=frame, 4=net */ + time_t updated_time; + int needs_update; } NW_NET_DEVICE; /* <========== DEVICES ==========> */ @@ -90,8 +93,9 @@ extern void handle_rip(int fd, int ipx_pack_typ, int data_len, IPX_DATA *ipxdata, ipxAddr_t *from_addr); +extern int activate_slow_net(uint32 net); -extern void insert_delete_server(uint8 *name, +extern void insert_delete_server(uint8 *name, int styp, ipxAddr_t *addr, ipxAddr_t *from_addr, diff --git a/nwshare.c b/nwshare.c new file mode 100644 index 0000000..b6774a2 --- /dev/null +++ b/nwshare.c @@ -0,0 +1,165 @@ +/* nwshare.c 21-Jul-97 */ + +/* (C)opyright (C) 1993,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 "nwvolume.h" +#include "nwfile.h" +#include "connect.h" + +#include "unxfile.h" +#include "nwshare.h" + +#define MAX_SH_OP_DEV 20 + +typedef struct { + int fd_r; + int fd_wr; + int in_use; + int dev; +} SH_OP_DEV; + +static SH_OP_DEV sh_op_devs[MAX_SH_OP_DEV]; +static int count_sh_op_dev=0; + +char *path_share_lock_files=NULL; + +int share_file(int dev, int inode, int sh_mode) +/* sh_mode + * 0 : remove share + * 1 : add_ro_r_share + * 4 : add_ro_w_share + * + * 2 : add_wr_r_share + * 8 : add_wr_w_share + * ---- + * 0x10 : test + */ +{ + int k = count_sh_op_dev; + int fr = -1; + int fo = -1; + int result = -1; + SH_OP_DEV *sod; + struct flock flockd; + + while (k--) { + sod=&(sh_op_devs[k]); + if (sod->fd_r < 0) { + fr=k; + } else if (sod->dev == dev) { + fo=k; + break; + } + } + + if ((!sh_mode) && fo==-1) { + XDPRINTF((1, 0, "Could not found share to remove")); + return(-1); + } + + if (fo==-1 && fr==-1) { + if (count_sh_op_dev < MAX_SH_OP_DEV) + fr=count_sh_op_dev++; + else { + XDPRINTF((1, 0, "Too much 'share devs'")); + return(-1); + } + } + + flockd.l_whence = SEEK_SET; + flockd.l_start = inode; + flockd.l_len = 1; + + if (!sh_mode) { + sod=&(sh_op_devs[fo]); + flockd.l_type = F_UNLCK; + (void)fcntl(sod->fd_r, F_SETLK, &flockd); + (void)fcntl(sod->fd_wr, F_SETLK, &flockd); + if (--sod->in_use < 1) { + close(sod->fd_r); + close(sod->fd_wr); + sod->fd_r = -1; + sod->fd_wr = -1; + sod->dev = -1; + } + } else { + if (fo == -1) { + char buff[300]; + int l; + sod=&(sh_op_devs[fr]); + if (NULL==path_share_lock_files) { + if (get_ini_entry(NULL, 41, buff, sizeof(buff)) && *buff) + new_str(path_share_lock_files, buff); + else + new_str(path_share_lock_files, "/var/spool/nwserv/.locks"); + seteuid(0); + unx_xmkdir(path_share_lock_files, 0755); + reseteuid(); + } + + l=sprintf(buff, "%s/%x.r", path_share_lock_files, dev); + seteuid(0); + if (-1 < (sod->fd_r=open(buff, O_RDWR|O_CREAT, 0600)) ) { + buff[l-1]='w'; + if (0 > (sod->fd_wr=open(buff, O_RDWR|O_CREAT, 0600) )){ + close(sod->fd_r); + sod->fd_r=-1; + } + } + reseteuid(); + + if (sod->fd_r < 0) { + XDPRINTF((1, 0, "Cannot open sharefile=`%s`", buff)); + return(-1); + } + sod->dev = dev; + } else + sod=&(sh_op_devs[fo]); + + if (!(sh_mode&0x10)){ + if (sh_mode & 1) { + flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK; + result=fcntl(sod->fd_r, F_SETLK, &flockd); + } else result=0; + + if ((!result) && (sh_mode & 2) ) { + flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK; + result=fcntl(sod->fd_wr, F_SETLK, &flockd); + } + + if (result) { + XDPRINTF((3, 0, "Cannot lock share sh_mode=%d", sh_mode)); + } else { + sod->in_use++; + } + } else { /* only testing */ + if (sh_mode & 1) { + flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK; + result=fcntl(sod->fd_r, F_GETLK, &flockd); + } else if (sh_mode & 2) { + flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK; + result=fcntl(sod->fd_wr, F_GETLK, &flockd); + } else result=-1; + return(flockd.l_type == F_UNLCK) ? 0 : -1; + } + } + return(result); +} + diff --git a/nwshare.h b/nwshare.h new file mode 100644 index 0000000..042d518 --- /dev/null +++ b/nwshare.h @@ -0,0 +1,8 @@ +/* nwshare.h: 20-Jul-97*/ +/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany + */ + +#ifndef _NWSHARE_H_ +#define _NWSHARE_H_ 1 +extern int share_file(int dev, int inode, int sh_mode); +#endif diff --git a/nwvolume.c b/nwvolume.c index 8cd0c0e..1665a7e 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 17-Jun-97 */ +/* nwvolume.c 20-Jul-97 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -36,6 +36,7 @@ NW_VOL *nw_volumes=NULL; int used_nw_volumes=0; uint8 *home_dir=NULL; int home_dir_len=0; +char *path_vol_inodes_cache=NULL; static int max_nw_vols=MAX_NW_VOLS; @@ -78,6 +79,7 @@ void nw_init_volumes(FILE *f) } rewind(f); used_nw_volumes = 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){ uint8 sysname[256]; @@ -93,6 +95,7 @@ void nw_init_volumes(FILE *f) new_str(vol->sysname, sysname); if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') { vol->options |= VOL_OPTION_IS_HOME; + vol->options |= VOL_OPTION_REMOUNT; unixname[0] = '\0'; len = 0; } else if (unixname[len-1] != '/') { @@ -151,6 +154,8 @@ void nw_init_volumes(FILE *f) if (vol->unixnamlen) volume_to_namespace_map(used_nw_volumes-1, vol); } + } else if (what==40) { /* path for vol/dev/inode->path cache */ + new_str(path_vol_inodes_cache, buff); } } /* while */ } @@ -357,11 +362,9 @@ int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu) return(volnr); } -int get_volume_options(int volnr, int mode) -/* returns >= 0 (options) if OK, else errocode < 0 */ -/* if mode > 0 and errcode then errorcode = 0 (nooptions) */ +int get_volume_options(int volnr) { - int result = (mode) ? 0 : -0x98; /* Volume not exist */; + int result = 0; if (volnr > -1 && volnr < used_nw_volumes) result = nw_volumes[volnr].options; XDPRINTF((5,0,"get_volume_options of VOLNR:%d, result=0x%x", volnr, result)); diff --git a/nwvolume.h b/nwvolume.h index 2fb6e36..693d457 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,4 +1,4 @@ -/* nwvolume.h 17-Jun-97 */ +/* nwvolume.h 20-Jul-97 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -71,13 +71,14 @@ extern NW_VOL *nw_volumes; extern int used_nw_volumes; extern uint8 *home_dir; extern int home_dir_len; +extern char *path_vol_inodes_cache; /* for namespace routines */ extern void nw_init_volumes(FILE *f); extern void nw_setup_home_vol(int len, uint8 *fn); extern int nw_get_volume_number(uint8 *volname, int namelen); extern int nw_get_volume_name(int volnr, uint8 *volname); extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu); -extern int get_volume_options(int volnr, int mode); +extern int get_volume_options(int volnr); extern int get_volume_inode(int volnr, struct stat *stb); extern int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota); extern int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse); diff --git a/tools.c b/tools.c index 76c2b7a..2c7fa94 100644 --- a/tools.c +++ b/tools.c @@ -287,13 +287,24 @@ int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize) return(0); } +static uint8 *path_bindery=NULL; + char *get_div_pathes(char *buff, char *name, int what, char *p, ... ) { char *wpath; int len; + uint8 locbuf[200]; switch (what) { case 0 : wpath = PATHNAME_PROGS; break; - case 1 : wpath = PATHNAME_BINDERY; break; + case 1 : if (path_bindery==NULL) { + if (get_ini_entry(NULL, 45, locbuf, sizeof(locbuf)) + && *locbuf) { + new_str(path_bindery, locbuf); + } else + new_str(path_bindery, PATHNAME_BINDERY); + } + wpath = path_bindery; + break; case 2 : wpath = PATHNAME_PIDFILES; break; default : buff[0]='\0'; return(buff); @@ -317,19 +328,6 @@ int get_ini_int(int what) return(-1); } -void get_ini_debug(int module) -/* what: - * 1 = nwserv - * 2 = ncpserv - * 3 = nwconn - * 4 = nwclient - * 5 = nwbind - * 6 = nwrouted - */ -{ - int debug = get_ini_int(100+module); - if (debug > -1) nw_debug = debug; -} static void sig_segv(int isig) { @@ -372,15 +370,30 @@ void get_debug_level(uint8 *buf) int i=sscanf((char*)buf, "%s %s", buf1, buf2); if (i > 0) { nw_debug=atoi((char*)buf1); + debug_mask=0; if (i > 1) { char dummy; if (sscanf(buf2, "%ld%c", &debug_mask, &dummy) != 1) sscanf(buf2, "%lx", &debug_mask); - } else - debug_mask=0; + } } } +void get_ini_debug(int module) +/* what: + * 1 = nwserv + * 2 = ncpserv + * 3 = nwconn + * 4 = nwclient + * 5 = nwbind + * 6 = nwrouted + */ +{ + uint8 buff[300]; + if (get_ini_entry(NULL, 100+module, buff, sizeof(buff))) + get_debug_level(buff); +} + void init_tools(int module, int options) { uint8 buf[300]; diff --git a/unxfile.c b/unxfile.c index 23cb593..fcdfb09 100644 --- a/unxfile.c +++ b/unxfile.c @@ -1,4 +1,4 @@ -/* unxfile.c: 20-Nov-96*/ +/* unxfile.c: 09-Jul-97*/ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -20,7 +20,6 @@ #include "net.h" #include "unxfile.h" -#if 1 int unx_mvdir(uint8 *oldname, uint8 *newname) { struct stat statb; @@ -47,8 +46,28 @@ int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname) return( (rename(oldname, newname) < 0) ? errno : 0); } +int unx_xmkdir(char *unixname, int mode) +{ + if (mkdir(unixname, mode)) { + char *p=unixname; + while (NULL != (p=strchr(p+1, '/'))) { + *p = '\0'; + if (!mkdir(unixname, mode)) + chmod(unixname, mode); + *p='/'; + } + if (!mkdir(unixname, mode)) { + chmod(unixname, mode); + return(0); + } + } else { + chmod(unixname, mode); + return(0); + } + return(-1); +} -#else +#if 0 int unx_mvdir(uint8 *oldname, uint8 *newname) { uint8 command[500]; diff --git a/unxfile.h b/unxfile.h index 393a2bc..0bd6e70 100644 --- a/unxfile.h +++ b/unxfile.h @@ -1,4 +1,4 @@ -/* unxfile.h: 18-Jun-97*/ +/* unxfile.h: 09-Jul-97*/ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -20,5 +20,6 @@ extern int unx_mvdir(uint8 *oldname, uint8 *newname); extern int unx_mvfile(uint8 *oldname, uint8 *newname); extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname); +extern int unx_xmkdir(char *unixname, int mode); #endif