From 1eac63223bd982f091ae7252cd4c0da56d0999c4 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 13 Nov 2011 00:38:57 +0100 Subject: [PATCH] mars_nwe-0.98.pl05 --- connect.c | 167 +++++++++--- connect.h | 36 ++- doc/BUGS | 36 +++ doc/CHANGES | 31 ++- doc/FAQS | 19 ++ doc/NEWS | 6 + doc/PIPE-FS | 36 +-- doc/PIPE-FS.ger | 41 +-- doc/mars_nwe.lsm | 6 +- emutli.c | 20 +- emutli.h | 2 - examples/comm.c | 2 +- examples/comm.exe | Bin examples/config.h | 10 +- examples/mk.li | 27 +- examples/nw.ini | 27 +- examples/sendm.c | 70 +++++ examples/unxcomm.c | 25 +- examples/unxsendm.c | 53 ++++ makefile.unx | 14 +- nameos2.c | 3 +- namspace.c | 651 ++++++++++++++++++++++++++++++++++---------- namspace.h | 12 +- ncpserv.c | 50 ++-- net.h | 53 ++-- net1.c | 158 +++++++++-- net1.h | 10 +- nwbind.c | 64 +---- nwconn.c | 58 ++-- nwdbm.c | 2 +- nwfile.c | 121 +++++--- nwfile.h | 7 +- nwqueue.c | 4 +- nwroute.c | 68 ++++- nwserv.c | 160 +++++------ nwvolume.c | 24 +- 36 files changed, 1506 insertions(+), 567 deletions(-) create mode 100644 doc/BUGS mode change 100755 => 100644 examples/comm.exe create mode 100644 examples/sendm.c create mode 100644 examples/unxsendm.c diff --git a/connect.c b/connect.c index d111599..ef76aea 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 04-Oct-96 */ +/* connect.c 07-Nov-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -42,7 +42,7 @@ int used_dirs=0; int act_uid=-1; int act_gid=-1; int act_obj_id=0L; /* not login */ -int entry8_flags=0; /* special login/logout/flags */ +int entry8_flags=0; /* special flags, see examples nw.ini, entry 8 */ int act_umode_dir=0; int act_umode_file=0; @@ -793,7 +793,7 @@ static int nw_path_ok(NW_PATH *nwpath) d++; } /* while */ if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff) - && (stbuff.st_mode & S_IFMT) == S_IFDIR) + && S_ISDIR(stbuff.st_mode)) return(stbuff.st_ino); result = -0x9c; /* wrong path */ } @@ -1009,48 +1009,56 @@ time_t nw_2_un_time(uint8 *d, uint8 *t) return(mktime(&s_tm)); } -static int un_nw_attrib(struct stat *stb, int attrib, int mode) +int un_nw_attrib(struct stat *stb, int attrib, int mode) /* mode: 0 = un2nw , 1 = nw2un */ { /* Attribute */ /* 0x01 readonly */ /* 0x02 hidden */ /* 0x04 System */ + /* 0x10 IS_DIR */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ /* TLINK (TCC 2.0) don't like it ???? */ if (!mode) { + int is_dir=S_ISDIR(stb->st_mode); /* UNIX access -> NW access */ - attrib = 0x20; + if (!is_dir) { + attrib = FILE_ATTR_A; + } else { + attrib = FILE_ATTR_DIR; + } if (act_uid) { /* if not root */ int acc=get_real_access(stb); if (!(acc & W_OK)) { - attrib |= 0x1; /* RO */ + attrib |= FILE_ATTR_R; /* RO */ } if (!(acc & R_OK)) { - attrib |= 0x2; /* We say hidden here */ + attrib |= FILE_ATTR_H; /* We say hidden here */ } } /* only shared if gid == gid && x Flag */ - if ((act_gid == stb->st_gid) && (stb->st_mode & S_IXGRP)) - attrib |= 0x80; /* shared flag */ + if (!is_dir) { + if ((act_gid == stb->st_gid) && (stb->st_mode & S_IXGRP)) + attrib |= FILE_ATTR_SHARE; /* shared flag */ + } return(attrib); } else { /* NW access -> UNIX access */ int mode = S_IRUSR | S_IRGRP; - if (attrib & 0x2) /* hidden */ + if (attrib & FILE_ATTR_H) /* hidden */ stb->st_mode &= ~mode; else stb->st_mode |= mode; mode = S_IWUSR | S_IWGRP; - if (attrib & 0x1) /* R/O */ + if (attrib & FILE_ATTR_R) /* R/O */ stb->st_mode &= ~mode; else stb->st_mode |= mode; - if (attrib & 0x80) /* Shared */ + if (attrib & FILE_ATTR_SHARE) /* Shared */ stb->st_mode |= S_IXGRP; else stb->st_mode &= ~S_IXGRP; @@ -1058,6 +1066,36 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode) } } +int un_nw_rights(struct stat *stb) +/* returns eff rights of file/dir */ +/* needs some more work */ +{ + int rights=0xfb; /* first all rights, but not TRUSTEE_O */ + if (act_uid) { + /* if not root */ + int is_dir = S_ISDIR(stb->st_mode); + int acc=get_real_access(stb); + int norights= TRUSTEE_A; /* no access control rights */ + if (!(acc & W_OK)) { + if (is_dir) { + norights |= TRUSTEE_C; + norights |= TRUSTEE_E; + } else { + norights |= TRUSTEE_W; /* RO */ + } + } + if (!(acc & R_OK)) { + if (is_dir) { + norights |= TRUSTEE_F; /* SCAN */ + } else { + norights |= TRUSTEE_R; /* Not for Reading */ + } + } + rights &= ~norights; + } else rights|= TRUSTEE_S; /* Supervisor */ + return(rights); +} + static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { @@ -1088,8 +1126,12 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name)); d->attrib=0; /* d->name could be too long */ upstr(d->name); - d->attrib = 0x10; /* Verzeichnis */ + d->attrib = (uint8) un_nw_attrib(stb, 0, 0); +#if 0 /* changed: 02-Nov-96 */ d->ext_attrib = 0xff; /* effektive rights ?? */ +#else + d->ext_attrib = (uint8) un_nw_rights(stb); /* effektive rights ?? */ +#endif un_date_2_nw(stb->st_mtime, d->create_date, 1); un_time_2_nw(stb->st_mtime, d->create_time, 1); U32_TO_BE32(get_file_owner(stb), d->owner_id); @@ -1277,8 +1319,14 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, NW_PATH zielpath; int completition=conn_get_kpl_path(&quellpath, dir_handle, q, qlen, 0); if (!completition > -1){ +#if 1 + /* I do not know anymore why I did these ??? */ memcpy(&zielpath, &quellpath, sizeof(NW_PATH)); strmaxcpy(zielpath.fn, z, zlen); +#else + /* and NOT these, perhaps this will also be ok ?! -- TODO -- */ + 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); @@ -1286,6 +1334,11 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, (optz & VOL_OPTION_IS_PIPE)) completition = -0x8b; else if ((optq & VOL_OPTION_READONLY) || (optz & VOL_OPTION_READONLY)) completition = -0x8b; + /* patch from Sven Norinder :09-Nov-96 */ + else if (optz & VOL_OPTION_DOWNSHIFT) + downstr(zielpath.fn); + else + upstr(zielpath.fn); } if (completition > -1){ int result; @@ -1353,7 +1406,7 @@ static int change_dir_entry( NW_DIR *dir, int volume, void nw_exit_connect(void) { if (connect_is_init) { - init_file_module(); + init_file_module(-1); } } @@ -1386,7 +1439,7 @@ int nw_init_connect(void) d++; } - init_file_module(); + init_file_module(-1); if (connect_is_init) { k = 0; @@ -1458,6 +1511,7 @@ int nw_free_handles(int task) } d++; } + init_file_module(task); } return(0); } @@ -1591,7 +1645,7 @@ int nw_open_dir_handle( int dir_handle, /* * Routine returns handle to use in searchroutines. - * RETURN=errcode ( <0 ) or ACCES Rights + * RETURN=errcode ( <0 ) or eff. ACCES Rights */ { @@ -1603,11 +1657,13 @@ int nw_open_dir_handle( int dir_handle, completition = new_dir_handle((ino_t)completition, &nwpath); if (completition > -1) { + struct stat stb; DIR_HANDLE *dh = &(dir_handles[completition-1]); + stat(dh->unixname, &stb); *volume = dh->volume; *dir_id = completition; *searchsequence = MAX_U16; - completition = 0xff; /* all rights */ + completition = (uint8)un_nw_rights(&stb); /* eff. rights */ } XDPRINTF((5,0,"NW_OPEN_DIR_2: completition = 0x%x", completition)); @@ -1636,24 +1692,32 @@ int nw_free_dir_handle(int dir_handle, int task) } else return(-0x9b); /* wrong handle */ } +int alter_dir_handle(int targetdir, int volume, uint8 *path, + int inode, int task) +/* targetdir will be changed */ +{ + if (targetdir > 0 && --targetdir < used_dirs + && dirs[targetdir].is_temp != 2) { + /* do not change special temphandles */ + XDPRINTF((5,0,"Change dhandle:%d(%d) -> '%d:%s'", targetdir+1, task, + volume, path)); + return(change_dir_entry(&dirs[targetdir], + volume, path, inode, + -1, -1, 0, task)); + /* here the existing handle is only modified */ + } else return(-0x9b); /* BAD DIR Handle */ +} + + int nw_set_dir_handle(int targetdir, int dir_handle, uint8 *data, int len, int task) /* targetdirs gets path of dirhandle + data */ { NW_PATH nwpath; int inode = conn_get_kpl_path(&nwpath, dir_handle, data, len, 1); - if (inode > -1){ - if (targetdir > 0 && --targetdir < used_dirs - && dirs[targetdir].is_temp != 2) { - /* do not change special temphandles */ - XDPRINTF((2,0,"Change dhandle:%d(%d) -> `%s`", targetdir+1, task, - conn_get_nwpath_name(&nwpath))); - return(change_dir_entry(&dirs[targetdir], - nwpath.volume, nwpath.path, inode, - -1, -1, 0, task)); - /* here the existing handle is only modified */ - } else return(-0x9b); /* BAD DIR Handle */ - } + if (inode > -1) + inode = alter_dir_handle(targetdir, nwpath.volume, nwpath.path, + inode, task); return(inode); /* invalid PATH */ } @@ -1698,15 +1762,15 @@ int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus) if (completition < 0) return(completition); strcpy(unname, build_unix_name(&nwpath, 0)); if (stat(unname, &stbuff) || - (!modus && (stbuff.st_mode & S_IFMT) != S_IFDIR) ) { + (!modus && !S_ISDIR(stbuff.st_mode)) ) { completition = -0x9c; - } else completition=0xff; /* all rights */ + } else completition=un_nw_rights(&stbuff); /* eff. rights */ return(completition); } int nw_creat_open_file(int dir_handle, uint8 *data, int len, NW_FILE_INFO *info, int attrib, int access, - int creatmode) + int creatmode, int task) /* * creatmode: 0 = open | 1 = creat | 2 = creatnew & 4 == save handle * attrib ?? @@ -1718,7 +1782,7 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len, if (completition > -1) { struct stat stbuff; completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0), - &stbuff, attrib, access, creatmode); + &stbuff, attrib, access, creatmode, task); if (completition > -1) get_file_attrib(info, &stbuff, &nwpath); @@ -1771,7 +1835,7 @@ static int s_nw_scan_dir_info(int dir_handle, U32_TO_BE32(get_file_owner(&stbuff), owner); un_date_2_nw(stbuff.st_mtime, subdatetime, 1); un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1); - return(0xff); + return(un_nw_rights(&stbuff)); } strcpy((char*)dirname, (char*)wild); } /* while */ @@ -1784,7 +1848,7 @@ static int s_nw_scan_dir_info(int dir_handle, U32_TO_BE32(get_file_owner(&stbuff), owner); un_date_2_nw(stbuff.st_mtime, subdatetime, 1); un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1); - return(0xff); + return(un_nw_rights(&stbuff)); } } /* return(-0x9c); NO MORE INFO */ @@ -1824,7 +1888,8 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, int volume, uint8 *path) { - uint8 spath[14]; + uint8 spath[14]; + uint32 nw_owner=get_file_owner(stb); int voloptions=get_volume_options(volume, 1); f->namlen=min(strlen((char*)path), 12); strmaxcpy(spath, path, 12); @@ -1839,9 +1904,12 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); un_date_2_nw(stb->st_mtime, f->created.date, 0); un_time_2_nw(stb->st_mtime, f->created.time, 0); + U32_TO_BE32(nw_owner, f->created.id); + + un_date_2_nw(stb->st_mtime, f->updated.date, 0); + un_time_2_nw(stb->st_mtime, f->updated.time, 0); + U32_TO_BE32(nw_owner, f->updated.id); - U32_TO_BE32(get_file_owner(stb), f->created.id); - memcpy(&(f->updated), &(f->created), sizeof(NW_DOS_FILE_INFO)); un_date_2_nw(stb->st_atime, f->last_access_date, 0); U32_TO_32(stb->st_size, f->size); } @@ -1856,7 +1924,7 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, strmaxcpy(spath, path, 12); upstr(spath); strncpy((char*)f->name, (char*)spath, f->namlen); - f->attributes[0] = 0x10; /* Dir */ + f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); un_date_2_nw(stb->st_mtime, f->created.date,0); un_time_2_nw(stb->st_mtime, f->created.time,0); U32_TO_BE32(get_file_owner(stb), f->created.id); @@ -1893,7 +1961,7 @@ int nw_scan_a_directory(uint8 *rdata, conn_get_nwpath_name(&nwpath), stbuff.st_uid, stbuff.st_gid)); - if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) { + if ( S_ISDIR(stbuff.st_mode)) { get_dos_dir_attrib(&(scif->u.d), &stbuff, nwpath.volume, nwpath.fn); } else { @@ -1936,7 +2004,6 @@ static int my_match(uint8 *s, uint8 *p) } else if (dot) { if (dot++ > 3) return(0); } else if (len == 8) return(0); - if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s)) || (*p | 0x20) != (*s | 0x20))) return(0); @@ -1949,10 +2016,26 @@ static int get_match(uint8 *unixname, uint8 *p) { DIR *d; uint8 *pp; +#if 0 + uint8 *p1; +#endif + int inode=0; if (!p || !*p) return(1); *p = '\0'; pp=p+1; while (*pp == '/') ++pp; +#if 0 + p1=strchr(pp, '/'); + if (!p1) p1=pp+strlen(pp); + if (p1 > pp+4 && *(p1-4) == '.' + && *(p1-3) == '_' + && *(p1-2) == '_' + && *(p1-1) == '_' ) { + *(p1-4) = '\0'; + inode=atoi(pp); + *(p1-4) = '.'; + } +#endif if (NULL != (d=opendir(unixname))) { struct dirent *dirbuff; XDPRINTF((10, 0, "opendir OK unixname='%s' pp='%s'", unixname, pp)); @@ -1961,7 +2044,7 @@ static int get_match(uint8 *unixname, uint8 *p) int len; if (dirbuff->d_ino) { XDPRINTF((10, 0, "get match found d_name='%s'", dirbuff->d_name)); - if (0 != (len=my_match(dirbuff->d_name, pp))) { + if ((dirbuff->d_ino ==inode) || 0 != (len=my_match(dirbuff->d_name, pp))) { memcpy(pp, dirbuff->d_name, len); XDPRINTF((10, 0, "get match, match OK")); closedir(d); diff --git a/connect.h b/connect.h index 4e7639f..fd4fd5a 100644 --- a/connect.h +++ b/connect.h @@ -1,6 +1,30 @@ -/* connect.h 29-Sep-96 */ +/* connect.h 06-Nov-96 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ + +/* some TRUSTEE defines */ +#define TRUSTEE_R 0x01 /* Read Rights */ +#define TRUSTEE_W 0x02 /* Write Rights */ +#define TRUSTEE_O 0x04 /* Open, not used ?? by Novell */ +#define TRUSTEE_C 0x08 /* Creat */ +#define TRUSTEE_E 0x10 /* Erase */ +#define TRUSTEE_A 0x20 /* Access Control */ +#define TRUSTEE_F 0x40 /* File Scan */ +#define TRUSTEE_M 0x80 /* Modify */ +/* ........................................ */ +#define TRUSTEE_S 0x100 /* Supervisor */ + + +/* <-------------- File Attributes -------------> */ +#define FILE_ATTR_NORMAL 0x00000000 +#define FILE_ATTR_R 0x00000001 +#define FILE_ATTR_H 0x00000002 +#define FILE_ATTR_S 0x00000004 +#define FILE_ATTR_DIR 0x00000010 +#define FILE_ATTR_A 0x00000020 +#define FILE_ATTR_SHARE 0x00000080 + + typedef struct { DIR *f; char unixname[256]; /* kompletter unixname */ @@ -112,7 +136,7 @@ extern void nw_exit_connect(void); extern int nw_free_handles(int task); extern int nw_creat_open_file(int dir_handle, uint8 *data, int len, - NW_FILE_INFO *info, int attrib, int access, int mode); + NW_FILE_INFO *info, int attrib, int access, int mode, int task); extern int nw_delete_datei(int dir_handle, uint8 *data, int len); extern int nw_set_file_information(int dir_handle, uint8 *data, int len, @@ -165,6 +189,9 @@ extern int nw_open_dir_handle( int dir_handle, extern int nw_free_dir_handle(int dir_handle, int task); +extern int alter_dir_handle(int targetdir, int volume, uint8 *path, + int inode, int task); + extern int nw_set_dir_handle(int targetdir, int dir_handle, uint8 *data, int len, int task); @@ -198,11 +225,10 @@ extern int used_dirs; extern int act_uid; extern int act_gid; extern int act_obj_id; /* not login == 0 */ +extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */ extern int act_umode_dir; extern int act_umode_file; -extern int entry8_flags; /* special login/logout/flags */ - extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, uint8 *data, int len, int only_dir) ; extern int conn_get_kpl_unxname(char *unixname, @@ -233,6 +259,8 @@ extern int fn_dos_match(uint8 *s, uint8 *p, int options); extern void un_date_2_nw(time_t time, uint8 *d, int high_low); extern time_t nw_2_un_time(uint8 *d, uint8 *t); +extern int un_nw_attrib(struct stat *stb, int attrib, int mode); +extern int un_nw_rights(struct stat *stb); extern void un_time_2_nw(time_t time, uint8 *d, int high_low); diff --git a/doc/BUGS b/doc/BUGS new file mode 100644 index 0000000..c017160 --- /dev/null +++ b/doc/BUGS @@ -0,0 +1,36 @@ +If you have problems. +--------------------- +- LOOK FOR KERNEL IPX CODE INSTALLED. + CONFIG_IPX=y (or m and ipx modul loaded (insmod ipx)). +- Look for using NO 'full internal net'. (kernel switch) + CONFIG_IPX_INTERN=n. +- Please always read doc/INSTALL[.ger], doc/README[.ger], + doc/FAQS and examples/nw.ini. + Very important sections in nwserv.conf(nw.ini) are: + Section 1: volumes + Section 3: Number of the internal network + Section 4: IPX-devices + Section 6: version-"spoofing" + Section 12: supervisor-login + If you do not have success, please make one try with + the distributed config file(s) without changing it. +- Important NEWS are reported in doc/NEWS. +- set nwserv.conf debug switches 101 .. 10x to '1', + make a new try with a new started nwserv and look + into the log-file (/tmp/nw.log). + Perhaps you can recognize the problem. :) + +some short notes for problem- or bug-reports. +--------------------------------------------- +- report your running environment + full mars_nwe version, example: 0.98.pl5 + linux-kernel, 2.0.23 + exact typ of client (NCPFS, DOS (NETX,VLM), OS/2, Win .. ) + changes you made into nwserv.conf(nw.ini), config.h. +- report whether your client runs correct under a 'real Novell-Server'. + ( if you have one ;) ) + +Known problems / solutions: +--------------------------- +- see doc/FAQS + diff --git a/doc/CHANGES b/doc/CHANGES index 78418eb..68d9fab 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 : 04-Oct-96 +Aenderungen in mars_nwe bis zum : 09-Nov-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -187,7 +187,7 @@ Erste 'oeffentliche' Version - nwserv.stations erweitert um 'station connect restrictions'. - Datei Access um 'supplementary groups' erweitert. Open File ruft gegebenfalls setegid() auf. -- Als File-Creator wird nun der aktuelle mars_nwer User zurueckgegeben, +- Als File-Creator wird nun der aktuelle mars_nwe User zurueckgegeben, falls st_uid == uid aktueller User. - call 0x3d in 0x3b (commit file) umbenannt. - segmentation violation in build_verz_name (connect.c) korrigiert. @@ -219,4 +219,31 @@ Erste 'oeffentliche' Version Sonderbehandlung von handle 1. - Login Restrictions. (station restrictions) eingebaut. <----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Namespace Routinen (0x57), Unterfunktionen: + 0x09 : (Set Short Dir Handle) + 0x14 : (Search For File Or Subdir Set) + 0x1c : (Get Full Path String) + 0x1d : (Get eff rights) + eingebaut. ( fuer client32 ) +- call 0x18 (EndOfJob) schliesst nun alle noch offenen Dateien + der aktuellen Task. +- File Server Copy (0x4a) funktioniert nun korrekt. +- neuer Schalter in config.h eingebaut: 'HANDLE_ALL_SAP_TYPS' + dadurch wird nicht nur TYP 4 herausgefiltert, sondern es werden + alle SAP-Typen in die ServerTabelle bzw. Bindery eingetragen. + Anregung von paul.sweetland@bbc.co.uk. +- sicheres Protokoll zwischen nwserv u. nwbind bzw. ncpserv + eingebaut. +- Schalter 302 erweitert um 0x2 fuer split Routing Datei. +- OS/2 namespace Dateimatchroutine abgeaendert, so dass Wildcard + '*.*' auf alle Dateien funktioniert. +- sehr einfache eff. rights Emulation eingebaut. +- NCP responses task ist nun gleich request task. +- Entry 8 um Schalter 0x2 erweitert. +- Openfile routine, share open etwas abgeaendert. +- IPX_MAX_DATA vergroessert. IPX_DATA_GR_546 abgeaendert. +- kleinen patch ( upper/lowercase Handling ) von + Sven Norinder + in nwconn,mv_dir eingebaut. +<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/FAQS b/doc/FAQS index 6f9f76d..9a51243 100644 --- a/doc/FAQS +++ b/doc/FAQS @@ -12,3 +12,22 @@ A: This is for automatic inserting UNIX Users as mars_nwe users. All of these automatic inserted users will get the password as the crypted bindery password. +Q: File write will 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 + know, but versions dated October 1994 or later are working for us. + ( John Rigby ) + +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 + 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 + settings. Here is a registry import file: + REGEDIT4 + [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\NWREDIR] + "SupportLFN"=hex:02 + diff --git a/doc/NEWS b/doc/NEWS index 4077389..bd49b4a 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,10 @@ # in this files are some notes for user of mars_nwe. +------09-Nov-96--- 0.98.pl5 ---------- +- now Novell Client32 should works. +- new config.h flag. 'HANDLE_ALL_SAP_TYPS' +- section 8: new flag 0x2 added. (see examples/nw.ini). +- section 302: enhanced for 'split routing info file'. +- config.h: 'IPX_DATA_GR_546' enhanced. ------04-Oct-96--- 0.98.pl4 ---------- - new sections 8 + 9 in nw.ini (nwserv.conf). Section 8: special login/logout/security flags. diff --git a/doc/PIPE-FS b/doc/PIPE-FS index 107d711..95d3d34 100644 --- a/doc/PIPE-FS +++ b/doc/PIPE-FS @@ -5,9 +5,10 @@ solve this problem In the PIPE filesystem either shell scripts or Linux programs can be stored. These programs are treated on the client side (eg DOS) like -simple files. Opening these files via the client causes a popen of the -programs. The server passes as the first parameter either CREAT READ -or WRITE, depending on the mode of the corresponding openfile +simple files. Reading or writing these files via the client causes +a popen of the programs. +The server passes as the first parameter either READ +or WRITE, depending on the mode of the corresponding first read or write operation. This allows the PIPE filesystem to provide a direct interface between client applications and Linux programs. @@ -16,8 +17,6 @@ simple shell script, which was stored in the PIPE-filesystem: #!/bin/sh case "$1" in -'CREAT') - ;; 'WRITE') cd /u3 && tar -xf - 2>> /tmp/tar.in # restore directory /u3/mar @@ -38,28 +37,15 @@ the Copy command (->save), or the local file can be copied into this A simple print operation can be achieved with the following script: #!/bin/sh -case "$1" in -'WRITE') - /usr/bin/lpr - ;; -*) - ;; -esac +/usr/bin/lpr +This allows you to print under dos/windows without capturing. - -Various unix programs can be invoked with the following script, after -it has been linked with the required program name. - -#!/bin/sh -case "$1" in -'READ') - /usr/bin/`basename $0` - ;; -*) - ;; -esac - +In the examples dir exist the two programpairs comm<->unxcomm +and sendm<->unxsendm as additional examples for using 'PIPE-filesystem'. +With comm/unxcomm it is very easy to start simple Linux programs +by your client. +for examples: ps, lpq, lprm ... I would appreciate hearing about further documented applications of the PIPE filesystem or suggestions for other ways of using it. diff --git a/doc/PIPE-FS.ger b/doc/PIPE-FS.ger index 9abd9c1..f78ee14 100644 --- a/doc/PIPE-FS.ger +++ b/doc/PIPE-FS.ger @@ -6,12 +6,12 @@ Ein schneller Loesungsansatz ergab das 'PIPE Filesystem'. In dem Pipe Filesystem koennen Shell Scripte oder Linux Programme hinterlegt werden. -Diese Programme werden bei dem Client (z.B. DOS) wie einfache +Diese Programme werden von dem Client (z.B. DOS) wie einfache Dateien behandelt. -Ein Oeffnen dieser Dateien ueber den Client bewirkt +Ein Lese oder Schreibzugriff auf diese Dateien ueber den Client bewirkt einen popen dieser Programme. Der Server uebergibt -als 1. Parameter entweder 'CREAT', 'READ' oder 'WRITE' -je nach Modus der jeweiligen Openfile Operation. +als 1. Parameter entweder 'READ' oder 'WRITE' +je nach Modus des ersten Zugriffes (Read oder Write). Das 'PIPE-Filesystem' bietet damit eine direkte Schnittstelle zwischen Client Anwendungen und Linux Programmen. @@ -20,8 +20,6 @@ Shell Script, welches im PIPE-Filesystem hinterlegt wurde. #!/bin/sh case "$1" in -'CREAT') - ;; 'WRITE') cd /u3 && tar -xf - 2>> /tmp/tar.in # restore directory /u3/mar @@ -39,31 +37,22 @@ lokale Datei 'kopiert' werden ( -> Sichern ) bzw. es kann die lokale Datei auf diese 'Pipe Datei' kopiert werden. ( -> Ruecksichern ) -Ein einfaches Drucken kann z.B. mit folgendem Script realisiert werden. -#!/bin/sh -case "$1" in -'WRITE') - /usr/bin/lpr - ;; -*) - ;; -esac - -Der Aufruf diverser Unix Programme kann mit folgenden Script -erfolgen das auf die entsprechenden Programmnamen gelinkt wurde. +Ein einfaches Drucken kann z.B. mit folgendem Mini Script realisiert werden. +Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf +/usr/bin/lpr. #!/bin/sh -case "$1" in -'READ') - /usr/bin/`basename $0` - ;; -*) - ;; -esac +/usr/bin/lpr +Dadurch kann ein capture unter DOS/Windows entfallen. + +In dem Verzeichnis examples gibt es als zusaetzliches Beispiel +die Programmpaare unxcomm<->comm und sendm<->unxsendm. +Mittels unxcomm/comm ist es sehr einfach moeglich einige +Linux Befehle vom Client aus aufzurufen. +z.B. : ps, lpq, lprm usw. Ueber weitere dokumentierte Anwendungen bzw. Anregungen zu dem PIPE-Filesystem wuerde ich mich freuen. Martin - diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 354db6a..64bba0a 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98.pl4 -Entered-date: 04-Oct-96 +Version: 0.98.pl5 +Entered-date: 11-Nov-96 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.pl4.tgz + 200kB mars_nwe-0.98.pl5.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Copying-policy: GNU diff --git a/emutli.c b/emutli.c index 4104870..7b66256 100644 --- a/emutli.c +++ b/emutli.c @@ -1,5 +1,5 @@ #define DO_IPX_SEND_TEST 1 -/* emutli.c 28-Apr-96 */ +/* emutli.c 04-Oct-96 */ /* * One short try to emulate TLI with SOCKETS. */ @@ -51,16 +51,18 @@ void set_sock_debug(int sock) } } -void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so) -{ - memcpy(i->net, &so->sipx_network, IPX_NET_SIZE + IPX_NODE_SIZE); - memcpy(i->sock, &so->sipx_port, 2); +#define sock2ipxadr(i, so) \ +{ \ + memcpy((i)->net, &(so)->sipx_network, IPX_NET_SIZE + IPX_NODE_SIZE); \ + (i)->sock[0] = ((uint8*)(&(so)->sipx_port))[0]; \ + (i)->sock[1] = ((uint8*)(&(so)->sipx_port))[1]; \ } -void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i) -{ - memcpy(&so->sipx_network, i->net, IPX_NET_SIZE + IPX_NODE_SIZE); - memcpy(&so->sipx_port, i->sock, 2); +#define ipx2sockadr(so, i) \ +{ \ + memcpy(&(so)->sipx_network, (i)->net, IPX_NET_SIZE + IPX_NODE_SIZE); \ + ((uint8*)(&(so)->sipx_port))[0] = (i)->sock[0]; \ + ((uint8*)(&(so)->sipx_port))[1] = (i)->sock[1]; \ } void set_emu_tli(void) diff --git a/emutli.h b/emutli.h index 6049e45..662e9c4 100644 --- a/emutli.h +++ b/emutli.h @@ -94,8 +94,6 @@ struct pollfd { extern void set_locipxdebug(int debug); extern void set_sock_debug(int sock); -extern void sock2ipxadr(ipxAddr_t *i, struct sockaddr_ipx *so); -extern void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i); extern void set_emu_tli(void); extern int poll(struct pollfd *fds, unsigned long nfds, int timeout); diff --git a/examples/comm.c b/examples/comm.c index 7504e64..7f580e3 100644 --- a/examples/comm.c +++ b/examples/comm.c @@ -30,7 +30,7 @@ static int usage(char *progname) int main(int argc, char **argv) { - char *unxcomm=getenv("UNXCOMM"); + char *unxcomm=getenv(ENV_UNXCOMM); if (NULL == unxcomm) unxcomm=DEFAULT_COMM; if (argc > 1) { int fdout = open(unxcomm, O_RDWR); diff --git a/examples/comm.exe b/examples/comm.exe old mode 100755 new mode 100644 diff --git a/examples/config.h b/examples/config.h index 4bc7381..547e745 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,4 +1,4 @@ -/* config.h: 18-Jul-96 */ +/* config.h: 04-Nov-96 */ /* some of this config is needed by make, others by cc */ #define DO_DEBUG 1 /* compile in debug code */ @@ -32,7 +32,9 @@ #define MAX_CONNECTIONS 5 /* max. number of simultaneous */ /* connections handled by mars_nwe */ -#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ +#define IPX_DATA_GR_546 1 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */ + /* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */ + /* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */ #define USE_MMAP 1 /* use mmap systen call */ @@ -58,6 +60,10 @@ #define MAX_NW_SERVERS 40 /* max. number of nw-servers on your */ /* network */ +#define HANDLE_ALL_SAP_TYPS 0 /* if set to 0 only SAP-Typ 4 Servers */ + /* will be put into routing table and */ + /* if set to 1 all SAP Typs will be */ + /* used. */ /* <--------------- 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 54b0d71..f035532 100755 --- a/examples/mk.li +++ b/examples/mk.li @@ -1,5 +1,5 @@ #!/bin/sh -# mk.li 10-Jul-96 ### +# mk.li 19-Oct-96 # please edit this file ! mk() @@ -15,7 +15,25 @@ mk() if [ $V_VPATH = '..' ] ; then cd ..; fi - chmod 666 $ERRFILE + if [ -f $ERRFILE ] ; then + chmod 666 $ERRFILE + fi +} + +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 "=============================================================" } TOLOWER='tr "[A-Z]" "[a-z]"' @@ -23,7 +41,8 @@ UNX=`uname -s | $TOLOWER` MASCHINE=`uname -m` MK_PPID=$$ export MK_PPID -trap 'echo "Error: Try again :)" && exit 1' 1 + +trap 'print_error; exit 1' 1 case $UNX in linux) @@ -55,7 +74,7 @@ fi TMP=/tmp INSTALL=install ;; -########### USL UNIX ############## +########### SYSV (UnixWare) ############## unix_sv) V_VPATH="." OBJDIR="." diff --git a/examples/nw.ini b/examples/nw.ini index c6338e1..4b63b58 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 change: 04-Oct-96 +# last changed: 09-Nov-96 # This file specifies which Linux-resources (printers, users, directories) # should be accessible to the DOS-clients via "mars_nwe". Furthermore @@ -72,6 +72,7 @@ # # 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) @@ -91,7 +92,7 @@ # Examples: # 1 SYS /var/local/nwe/SYS k # 1 CDROM /cdrom kmr -# 1 HOME ~ k +# 1 HOME ~ km 1 SYS /u3/SYS/ k @@ -259,8 +260,11 @@ # # SERVER_VERSION: the version-number reported to DOS-clients # 0 Version 2.15 (default) -# 1 Version 3.11 -# 2 Version 3.12 (not implemented yet) +# 1 Version 3.11 (will be default soon) +# 2 Version 3.12 (burst mode is not implemented yet) +# +# If you want to use longfilenamesupport and/or namespace routines +# you should set this section to '1'. # ------------------------------------------------------------------------- # @@ -301,12 +305,16 @@ 7 0 -# Section 8: special login/logout/security flags. +# Section 8: special login/logout/security and other flags. # ========================================================================= # Flags # 0x1 allow changing dir/accessing other files than login/* # when not logged in, if the client supports it. # ( this was standard till mars_nwe-0.98.pl4 ) +# 0x2 switch on strange compatibility mode for opening files. +# If an opencall do an open for writing but +# the file is readonly then this call will not fail +# but open the file readonly. # # other flags may follow. # value will be interpreted as hex value. @@ -537,7 +545,7 @@ 101 1 # debug NWSERV 102 0 # debug NCPSERV 103 0 # debug NWCONN -104 0 # debug (start) NWCLIENT +104 0 # debug (start) NWCLIENT, should *always* be '0' ! 105 0 # debug NWBIND 106 1 # debug NWROUTED @@ -561,9 +569,12 @@ 300 1 # > 0 print routing info to file every x broadcasts. # ( normally minutes ) 301 /tmp/nw.routes # filename of logfile -302 1 # 1 = creat new routing info file - # 0 = append to this file +302 0x1 # flags will be interpreted as hex value. + # 0 = append to this file + # & 0x1 = creat new routing info file + # & 0x2 = split info into several files + # (extensions = .1, .2, .3 ... ) # Section 310: watchdogs diff --git a/examples/sendm.c b/examples/sendm.c new file mode 100644 index 0000000..663b763 --- /dev/null +++ b/examples/sendm.c @@ -0,0 +1,70 @@ +/* sendm.c 23-Oct-96 */ +/* + * simple demo for a sendmail acces under DOS + * DOS <-> UNX command handling using PIPE filesystem. + * can be used with unxsendm for UNX. + * + * Can also be used under Linux for ncpfs <-> mars_nwe. + * but do not use it directly (the opencall will destroy unxsendm)!! + * + * QUICK + DIRTY !!! + */ + +#define ENV_UNXCOMM "UNXSENDM" +#ifdef LINUX +# define DEFAULT_COMM "/pipes/unxsendm" +# else +# define DEFAULT_COMM "p:/unxsendm" +#endif + +#include +#include +#include +#ifndef LINUX +# include +#endif +#include + +int main(int argc, char **argv) +{ + char *unxcomm=getenv(ENV_UNXCOMM); + int fdout; + int fdin; + int is_pipe=isatty(0) ? 0 :1; + if (NULL == unxcomm) + unxcomm=DEFAULT_COMM; + fdout = open(unxcomm, O_RDWR); + fdin = dup(fdout); + if (fdout > -1 && fdin > -1) { + char **pp=argv+1; + unsigned char b=32; + int size; + char buf[1024]; + while(--argc >0) { + write(fdout, *pp, strlen(*pp)); + ++pp; + write(fdout, &b, 1); + } + b=0; + write(fdout, &b, 1); + close(fdout); + fdout=dup(fdin); + if (6 == (size = read(fdin, buf, 6)) && !memcmp(buf, "+++++\n", 6)) { + /* now write stdin -> sendmail */ + if (is_pipe) { + while (0 < (size = fread(buf, 1, sizeof(buf), stdin))) + write(fdout, buf, size); + } + } else if (size > 0) + write(1, buf, size); /* probably errormessage */ + close(fdout); + /* now we print errors */ + while (0 < (size = read(fdin, buf, sizeof(buf)))) { + write(1, buf, size); + } + close(fdin); + return(0); + } else + fprintf(stderr, "Cannot open PIPECOMMAND '%s'\n", unxcomm); + return(1); +} diff --git a/examples/unxcomm.c b/examples/unxcomm.c index 628fcca..e9c0d12 100644 --- a/examples/unxcomm.c +++ b/examples/unxcomm.c @@ -1,6 +1,12 @@ +/* unxcomm.c 24-Oct-96 */ /* simple UNX program to work together with 'comm' */ +/* to domonstrate usage of pipefilesystem */ + #include #include +#include +#include + static char **build_argv(int bufsize, char *command, int len) /* routine returns **argv for use with execv routines */ @@ -38,15 +44,28 @@ static char **build_argv(int bufsize, char *command, int len) } #define MAXARGLEN 1024 +int bl_read(int fd, void *buf, int size) +{ + fd_set fdin; + struct timeval t; + int result; + FD_ZERO(&fdin); + FD_SET(fd, &fdin); + t.tv_sec = 1; /* 1 sec should be enough */ + t.tv_usec = 0; + result = select(fd+1, &fdin, NULL, NULL, &t); + if (result > 0) + result=read(fd, buf, size); + return(result); +} + int main(int argc, char *argv[]) { - int status=fcntl(0, F_GETFL); int size; char buf[MAXARGLEN+1024]; - if (status != -1) fcntl(0, F_SETFL, status|O_NONBLOCK); close(2); dup2(1,2); - if (-1 < (size=read(0, buf, MAXARGLEN))){ + if (0 < (size=bl_read(0, buf, MAXARGLEN))){ char **argvv=build_argv(sizeof(buf), buf, size); if (argvv) { char path[300]; diff --git a/examples/unxsendm.c b/examples/unxsendm.c new file mode 100644 index 0000000..3eb8d73 --- /dev/null +++ b/examples/unxsendm.c @@ -0,0 +1,53 @@ +/* unxsendm.c 23-Oct-96 */ +/* simple UNX program to work together with 'pipe-filesystem' + * and DOS sendm.exe to get sendmail functionality under DOS + * QUICK + DIRTY !!! + */ + +#include +#include +#include +#include + +#define MAXARGLEN 100 + +int bl_read(int fd, void *buf, int size) +{ + fd_set fdin; + struct timeval t; + int result; + FD_ZERO(&fdin); + FD_SET(fd, &fdin); + t.tv_sec = 1; /* 1 sec should be enough */ + t.tv_usec = 0; + result = select(fd+1, &fdin, NULL, NULL, &t); + if (result > 0) + result=read(fd, buf, size); + return(result); +} + +int main(int argc, char *argv[]) +{ + int size; + char buf[1024]; + close(2); + dup2(1,2); /* we want stdout and errout */ + if (-1 < (size=bl_read(0, buf, MAXARGLEN))){ + FILE *f; + char path[MAXARGLEN+200]; + buf[size]='\0'; + sprintf(path, "/usr/sbin/sendmail %s", buf); + f=popen(path, "w"); + if (NULL != f) { + write(1, "+++++\n", 6); + while (0 < (size=bl_read(0, buf, sizeof(buf)))){ + fwrite(buf, size, 1, f); + } + pclose(f); + return(0); + } + perror(path); + } else + perror("read stdin"); + return(1); +} diff --git a/makefile.unx b/makefile.unx index d2d462d..18cfc90 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 11-Sep-96 +#makefile.unx 04-Oct-96 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=98 -P_L=4 +P_L=5 #define D_P_L 1 DISTRIB=mars_nwe @@ -118,6 +118,7 @@ OBJ8= $(OBJ6) OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ + nwqueue$(O) nameos2$(O) \ nwdbm$(O) nwcrypt$(O) unxlog$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ $(PROG7)$(O) $(PROG8)$(O) @@ -164,6 +165,8 @@ $(C)$(O): n_all: $(PROGS) @echo "don't forget to do a 'make install' as root !" >> $(VPATH)/.mk.notes + @echo "please take a look into doc/NEWS !" >> $(VPATH)/.mk.notes + n_routed: $(PROG7) @@ -191,7 +194,12 @@ echo "$(M_FILENAME_NW_INI) created from nw.ini"; \ echo ""; \ echo "********************************************************"; \ echo ""; \ -fi; cd $(OBJDIR) ) +fi; \ +echo "If you have problems, please read 'doc/BUGS' before"; \ +echo "sending mail to mailinglist or me."; \ +echo ""; \ +echo "********************************************************"; \ +cd $(OBJDIR) ) n_reboot: n_install -nwserv -k diff --git a/nameos2.c b/nameos2.c index 426ca86..dc2fac2 100644 --- a/nameos2.c +++ b/nameos2.c @@ -198,7 +198,8 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions) switch (pc) { case '.' : - case 1000: if (*s && ('.' != *s++) ) return(0); + case 1000: if ( (*p!= 0xff || (*(p+1) != '*' && *(p+1) != 0xaa)) + && *s && ('.' != *s++) ) return(0); break; case '?' : diff --git a/namspace.c b/namspace.c index 2d4716b..c5ed605 100644 --- a/namspace.c +++ b/namspace.c @@ -1,8 +1,7 @@ -/* namspace.c 09-Aug-96 : NameSpace Services, mars_nwe */ +/* namspace.c 09-Nov-96 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ -/* Its very dirty till now. */ -/* namespace calls should be only activated for testings */ +/* Its still very dirty, but it should work fairly well */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -284,15 +283,28 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, int k = -1; int npbeg = strlen(nwpath->path); uint8 *pp = nwpath->path+npbeg; - +#if 0 + int perhaps_inode_mode = 0; +#endif XDPRINTF((2, 0, "entry add_hpath_to_nwpath: %s", debug_nwpath_name(nwpath))); - while (!result && ++k < nwp->components) { int len = (int) *(pp_pathes++); uint8 *p = pp_pathes; pp_pathes+=len; - + if (!len) { /* this means '..' ! */ + if (pp > nwpath->path) { + pp=strrchr((char*)nwpath->path, '/'); + if (!pp) + pp=nwpath->path; + *pp='\0'; + npbeg = pp - nwpath->path; + continue; + } else { + result=-0x9c; /* wrong path */ + goto leave_build_nwpath; + } + } if (!k && nwpath->volume == -1) { /* first component is volume */ if ((nwpath->volume=nw_get_volume_number(p, len)) < 0) { /* something not OK */ @@ -310,8 +322,15 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, } while (i--) { - if (*p == 0xae) *pp++ = '.'; - else if (*p == 0xaa || *p == '*' ) { + if (*p == 0xae || *p == '.') { + *pp++ = '.'; +#if 0 + if (nwpath->namespace == NAME_DOS) { + if (i==3 && *(p+1) == '_') + perhaps_inode_mode++; + } +#endif + } else if (*p == 0xaa || *p == '*' ) { *pp++ = '*'; nwpath->has_wild++; } else if (*p == 0xbf || *p == '?' ) { @@ -334,7 +353,7 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, *pp = '\0'; } /* else */ } /* while */ - if (nwpath->volume < 0) result=-0x9c; + if (nwpath->volume < 0) result=-0x9c; /* wrong path */ leave_build_nwpath: if ((!result) && (!act_obj_id) && !(entry8_flags & 1)) { if (nwpath->volume) @@ -354,7 +373,7 @@ leave_build_nwpath: if (!result) { NW_VOL *v = &nw_volumes[nwpath->volume]; if (nwpath->namespace == NAME_DOS || nwpath->namespace == NAME_OS2) { - if (v->options & VOL_OPTION_IGNCASE) { + if (v->options & VOL_OPTION_IGNCASE /* || perhaps_inode_mode*/) { int nplen= (int)(pp - nwpath->path) - npbeg; uint8 unixname[1024]; /* should be enough */ memcpy(unixname, v->unixname, v->unixnamlen); @@ -376,6 +395,12 @@ leave_build_nwpath: downstr(nwpath->path); else upstr(nwpath->path); +#if 0 + if (nwpath->namespace == NAME_DOS){ + + + } +#endif } } } @@ -460,7 +485,6 @@ 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; @@ -594,6 +618,118 @@ static int build_base(int namespace, return(result); } +static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname) +{ + uint8 *ss=e->nwpath.fn; + int len=0; + int pf=0; + int is_ok=1; + int options=get_volume_options(e->nwpath.volume, 1); + for (; *ss; ss++){ + if (*ss == '.') { + if (pf++) { /* no 2. point */ + is_ok=0; + break; + } + len=0; + } else { + ++len; + if ((pf && len > 3) || len > 8) { + is_ok=0; + break; + } + if (!(options & VOL_OPTION_IGNCASE)){ + if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ + if (*ss >= 'A' && *ss <= 'Z') { + is_ok=0; + break; + } + } else { /* only upshift chars */ + if (*ss >= 'a' && *ss <= 'z') { + is_ok=0; + break; + } + } + } + } + } + if (is_ok) { + strcpy(fname, e->nwpath.fn); + upstr(fname); + return(strlen(fname)); + } else { + return(sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino)); + } +} + +#if 0 +typedef struct { + int anz; + DIR_BASE_ENTRY *ee[MAX_DIR_BASE_ENTRIES]; +} BASE_COMPONENTS; + +static BASE_COMPONENTS *get_path_components(DIR_BASE_ENTRY *dbe) +{ + BASE_COMPONENTS *be=(BASE_COMPONENTS*)xcmalloc(sizeof(BASE_COMPONENTS)); + uint8 *p=dbe->nwpath.path; + uint8 *lastpp = p+strlen(p); + int len=0; + int k=0; + int done=(lastpp==dbe->nwpath.path || + (lastpp==dbe->nwpath.path+1 && *(dbe->nwpath.path)== '/' )); + + + result = insert_get_base_entry(nwpath, namespace, 0); + + + + int l; + while (!done) { + uint8 *pp=lastpp; + while (pp > dbe->nwpath.path && *pp!='/') --pp; + if (*pp != '/') { + done++; + l = lastpp-pp; + } else { + pp++; + l = lastpp-pp; + lastpp=pp-1; + } + if (!k++) { + + + } else { + + } + + + if (l > 255) + return(-0xff); + len+=(l+1); + *(p++) = (uint8)l; + memcpy(p, pp, l); + *(p+l)='\0'; + k++; + XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p)); + p+=l; + } + /* now as last element the volume */ + l=strlen(nw_volumes[dbe->nwpath.volume].sysname); + len+=(l+1); + *(p++) = (uint8)l; + memcpy(p, nw_volumes[dbe->nwpath.volume].sysname, l); + *(p+l)='\0'; + k++; + XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p)); + + if (len > 400) + return(-0xff); /* we support only 'short' pathnames */ + +} + +#endif + + int nw_generate_dir_path(int namespace, NW_HPATH *nwp, uint8 *ns_dir_base, @@ -619,13 +755,15 @@ int nw_generate_dir_path(int namespace, return(result); } -static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) +static int build_dir_info(DIR_BASE_ENTRY *dbe, + int namespace, + uint32 infomask, uint8 *p) { N_NW_PATH *nwpath=&(dbe->nwpath); struct stat *stb=&(nwpath->statb); - int result = 76; + int result = 76; /* minimumsize */ uint32 owner = get_file_owner(stb); - memset(p, 0, result); + memset(p, 0, result+2); if (infomask & INFO_MSK_DATA_STREAM_SPACE) { U32_TO_32(stb->st_size, p); @@ -633,12 +771,11 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p += 4; if (infomask & INFO_MSK_ATTRIBUTE_INFO) { - uint32 mask=0L; - if (S_ISDIR(stb->st_mode)) mask |= FILE_ATTR_DIR; - U32_TO_32(mask, p); + uint32 attrib = (uint32) un_nw_attrib(stb, 0, 0); + U32_TO_32(attrib, p); p += 4; - U16_TO_16((uint16)(mask & 0xFFFF), p); - p +=2; + U16_TO_16((uint16)(attrib & 0xFFFF), p); + p += 2; } else p+=6; if (infomask & INFO_MSK_DATA_STREAM_SIZE) { @@ -658,7 +795,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p +=2; un_date_2_nw(stb->st_mtime, p, 0); p +=2; - U32_TO_32(owner, p); + U32_TO_BE32(owner, p); /* HI-LOW ! */ p +=4; } else p+=8; @@ -667,7 +804,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p +=2; un_date_2_nw(stb->st_mtime, p, 0); p +=2; - U32_TO_32(owner, p); + U32_TO_BE32(owner, p); /* HI-LOW ! */ p +=4; un_date_2_nw(stb->st_atime, p, 0); /* access date */ p +=2; @@ -678,12 +815,12 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p +=2; un_date_2_nw(0, p, 0); p +=2; - U32_TO_32(0, p); + U32_TO_BE32(0, p); /* HI-LOW */ p +=4; } else p+=8; - if (infomask & INFO_MSK_RIGHTS_INFO) { - U16_TO_16(0, p); + if (infomask & INFO_MSK_RIGHTS_INFO) { /* eff. rights ! */ + U16_TO_16( un_nw_rights(stb), p); } p +=2; @@ -710,21 +847,26 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) } else p+=12; if (infomask & INFO_MSK_NAME_SPACE_INFO){ - U32_TO_32(0, p); /* Creator of the name space number */ + U32_TO_32(namespace, p); /* using namespace */ } p +=4; /* ---------------------------------------------- */ if (infomask & INFO_MSK_ENTRY_NAME) { - *p = (uint8) strlen(nwpath->fn); result++; - if (*p) { - memcpy(p+1, nwpath->fn, (int) *p); + if (namespace == NAME_DOS) { + *p=(uint8) build_dos_name(dbe, p+1); result += (int) *p; + } else { + *p = (uint8) strlen(nwpath->fn); + if (*p) { + memcpy(p+1, nwpath->fn, (int) *p); + result += (int) *p; + } } } - XDPRINTF((3, 0, "build_dir_info:path=%s, result=%d, basehandle=0x%x, mask=0x%lx", - debug_nwpath_name(nwpath), result, dbe->basehandle, infomask)); + XDPRINTF((3, 0, "build_d_i:space=%d, path=%s, result=%d, handle=0x%x, mask=0x%lx", + namespace, debug_nwpath_name(nwpath), result, dbe->basehandle, infomask)); return(result); } int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, @@ -734,13 +876,14 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, /* returns sizeof info_mask * the sizeof info_mask is NOT related by the infomask. * But the _valid_ info is. + * must return -0xff for file not found ! */ { int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); if (result > -1) { DIR_BASE_ENTRY *dbe=dir_base[result]; nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); - result = build_dir_info(dbe, infomask, responsedata); + result = build_dir_info(dbe, destnamspace, infomask, responsedata); } else { XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", -result)); @@ -748,6 +891,25 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, return(result); } +int nw_get_eff_rights(int namespace, NW_HPATH *nwp, + int destnamspace, + int searchattrib, uint32 infomask, + uint8 *responsedata) +{ + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + nwp_stat(&(dbe->nwpath), "nw_get_eff_rights"); + U16_TO_16(un_nw_rights(&(dbe->nwpath.statb)), responsedata); + responsedata+=2; + result = 2+build_dir_info(dbe, destnamspace, infomask, responsedata); + } else { + XDPRINTF((3, 0, "nw_get_eff_rights NOT OK result=-0x%x", + -result)); + } + return(result); +} + static int nw_init_search(int namespace, NW_HPATH *nwp, uint8 *pathes, @@ -790,7 +952,7 @@ static int get_add_new_entry(DIR_BASE_ENTRY *qbe, int namespace, } static int namespace_fn_match(uint8 *s, uint8 *p, int namespace) -/* for other namespaces than DOS */ +/* for other namespaces than DOS + OS2 */ { int pc, sc; uint state = 0; @@ -880,18 +1042,30 @@ static int namespace_fn_match(uint8 *s, uint8 *p, int namespace) int nw_search_file_dir(int namespace, int datastream, - uint32 searchattrib, uint32 infomask, - int volume, uint32 basehandle, uint32 sequence, - int len, uint8 *path, uint8 *responsedata) + uint32 searchattrib, uint32 infomask, int *count, + int volume, uint32 basehandle, uint32 *sequence, + int len, uint8 *path, uint8 *info, int *perhaps_more) { - int result = find_base_entry(volume, basehandle); +static uint32 saved_sequence=0L; + + int max_counts = *count; + int found = 0; + int result = find_base_entry(volume, basehandle); + *perhaps_more = 0; + *count = 0; + if (len > 255) return(-0x9c); /* wrong path */ + if (result > -1) { 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)) ) { uint8 entry[257]; + uint8 *pe=entry; + int have_wild=0; + int inode_search=0; + uint8 *is_ap=NULL; /* one after point */ struct dirent *dirbuff; struct stat statb; int dest_entry=-1; @@ -899,13 +1073,40 @@ int nw_search_file_dir(int namespace, int datastream, ds->kpath = ds->unixname+strlen(ds->unixname); *(ds->kpath) = '/'; *(++(ds->kpath)) = '\0'; - if (sequence == MAX_U32) - sequence=0L; - if (sequence) - seekdir(ds->fdir, sequence); + if (*sequence == MAX_U32) { + saved_sequence=0L; + *sequence=0L; + } +#if 0 + if (saved_sequence) { + seekdir(ds->fdir, saved_sequence); + saved_sequence=0L; + } else +#endif + if (*sequence) + seekdir(ds->fdir, *sequence); dbe->locked++; - strmaxcpy(entry, path, min(255, len)); + + while (len--) { + uint8 c=*path++; + *pe++=c; + if (!have_wild) { + if (c==0xff) { + if (*path == '?' || *path == '*' + || *path == 0xae || *path == 0xbf || *path==0xaa) + have_wild++; + } else if (c == '.') is_ap=pe; + } + } + *pe='\0'; + + if (!have_wild && is_ap && pe - is_ap == 3 && *is_ap== '_' + && *(is_ap+1) == '_' && *(is_ap+2) == '_') { + *(is_ap -1) = '\0'; + inode_search=atoi(entry); + *(is_ap -1) = '.'; + } if ( (namespace == NAME_DOS || namespace == NAME_OS2) && !(vol_options & VOL_OPTION_IGNCASE) ) { @@ -916,30 +1117,31 @@ int nw_search_file_dir(int namespace, int datastream, } } - XDPRINTF((5,0,"nw_search_file_dir namspace=%d, searchpath='%s'", - namespace, entry)); + XDPRINTF((5,0,"nw_s_f_d namsp=%d,sequence=%d, search='%s'", + namespace, *sequence, entry )); while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){ uint8 *name=(uint8*)(dirbuff->d_name); if (dirbuff->d_ino && strlen((char*)name) < 256) { int flag; XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name)); - - if (namespace == NAME_DOS) { - flag = (*name != '.' && fn_dos_match(name, entry, vol_options)); - } else if (namespace == NAME_OS2) { - flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) - && fn_os2_match(name, entry, vol_options); - } else { - flag = (!strcmp(name, entry) - || namespace_fn_match(name, entry, namespace)); - } - + if (!inode_search) { + if (namespace == NAME_DOS) { + flag = (*name != '.' && fn_dos_match(name, entry, vol_options)); + } else if (namespace == NAME_OS2) { + flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) + && fn_os2_match(name, 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((5,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; + flag = (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL; if (!flag) { if (S_ISDIR(statb.st_mode)) flag=(searchattrib & FILE_ATTR_DIR); @@ -947,11 +1149,23 @@ int nw_search_file_dir(int namespace, int datastream, flag = !(searchattrib & FILE_ATTR_DIR); } if (flag) { - strcpy(entry, name); - if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) - break; - else { - XDPRINTF((1, 0, "nw_search_file_dir:Cannot add entry '%s'", entry)); + if (!found) { + strcpy(entry, name); + if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) { + found++; +#if 0 + if (max_counts > 1) { + saved_sequence = (uint32)telldir(ds->fdir); + /* for next turn */ + } else +#endif + 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", @@ -970,20 +1184,26 @@ int nw_search_file_dir(int namespace, int datastream, if (dest_entry > -1) { DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry]; (void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir"); - *responsedata = (uint8) volume; - responsedata++; - U32_TO_32(basehandle, responsedata); - responsedata+=4; - U32_TO_32((uint32)telldir(ds->fdir), responsedata); - responsedata+=4; - *responsedata = (uint8) 0; /* reserved */ - responsedata++; - result = 10 + - build_dir_info(dest_dbe, - infomask|INFO_MSK_NAME_SPACE_INFO, - responsedata); - } else +#if 0 + if (saved_sequence) + *sequence= saved_sequence; + else +#endif + *sequence= (uint32)telldir(ds->fdir); + /* if (found < 2) saved_sequence=0L; */ + result = build_dir_info(dest_dbe, datastream, + infomask |INFO_MSK_NAME_SPACE_INFO, + info); + *count=1; +#if 0 + *perhaps_more=(found==2) ? 0xff : 0; +#else + *perhaps_more=(have_wild) ? 0xff : 0; +#endif + } else { + saved_sequence=0L; result=-0xff; /* no files matching */ + } dbe->locked=0; closedir(ds->fdir); } /* if NULL != ds->fdir */ @@ -993,13 +1213,15 @@ int nw_search_file_dir(int namespace, int datastream, return(result); } -static int nw_open_creat_file_or_dir(int namespace, +static int nw_open_creat_file_or_dir( + int namespace, int opencreatmode, int attrib, uint32 infomask, uint32 creatattrib, int access_rights, NW_HPATH *nwp, uint8 *pathes, - uint8 *responsedata) + uint8 *responsedata, + int task) { int result = build_base(namespace, nwp, pathes, 0, NULL); int exist = result; @@ -1030,24 +1252,29 @@ static int nw_open_creat_file_or_dir(int namespace, #endif creatmode = 1; } + if ((result = file_creat_open(dbe->nwpath.volume, nwpath_2_unix(&dbe->nwpath, 2), &(dbe->nwpath.statb), - attrib, access_rights, creatmode)) > -1) { + attrib, access_rights, creatmode, task)) > -1) { fhandle = (uint32) result; +#if 0 actionresult |= OPC_ACTION_OPEN; /* FILE OPEN */ +#endif if (exist > -1 && (opencreatmode & OPC_MODE_REPLACE)) actionresult |= OPC_ACTION_REPLACE; /* FILE REPLACED */ } - } else result=-0xff; - } else if (exist > -1) result=-0x84; + } else + result=-0xff; + } else if + (exist > -1) result=-0x84; if (result > -1) { U32_TO_BE32(fhandle, responsedata); responsedata += 4; - *responsedata =(uint8) actionresult; - /* responsedata++ ; */ + *responsedata =(uint8) actionresult; + *(responsedata+1) = 0; responsedata+=2; - result = 6 + build_dir_info(dbe,infomask, responsedata); + result = 6 + build_dir_info(dbe, namespace, infomask, responsedata); } } XDPRINTF((3, 0, "nw_open_creat mode=0x%x, creatattr=0x%x, access=0x%x, attr=0x%x, result=%d", @@ -1099,6 +1326,91 @@ static int nw_alloc_short_dir_handle(int namespace, int hmode, return(result); } +static int nw_set_short_dir_handle(int namespace, int desthandle, + NW_HPATH *nwp, int task) +{ + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + if (S_ISDIR(dbe->nwpath.statb.st_mode)) { + result=alter_dir_handle(desthandle, + dbe->nwpath.volume, dbe->nwpath.path, + dbe->nwpath.statb.st_ino, task); + } else result=-0x9c; /* wrong path */ + } + return((result > 0) ? 0 : result); +} + +static int nw_get_full_path_cookies(int namespace, + int destnamspace, + NW_HPATH *nwp, int *cookieflags, + uint32 *cookie1, uint32 *cookie2, + int *components, uint8 *componentpath) + +/* SIMPLE IMPLEMENTATION, needs more work !!!! */ +{ + int result = build_base(namespace, nwp, nwp->pathes, 0, NULL); + if (result > -1) { + DIR_BASE_ENTRY *dbe=dir_base[result]; + uint8 *p = componentpath; + uint8 *lastpp = dbe->nwpath.path+strlen(dbe->nwpath.path); + int len=0; + int k=0; + int done=(lastpp==dbe->nwpath.path || + (lastpp==dbe->nwpath.path+1 && *(dbe->nwpath.path)== '/' )); + int l; + if (*cookie1 != MAX_U32 || *cookie2 != MAX_U32) + return(-0xff); + if (strlen(dbe->nwpath.path) > 256) + return(-0xfb); /* we do support 'short' pathnames only */ + + while (!done) { + uint8 *pp=lastpp; + while (pp > dbe->nwpath.path && *--pp !='/');; + if (*pp == '/') { + if (pp < dbe->nwpath.path + 2) ++done; + pp++; + l = lastpp-pp; + lastpp = pp-1; + } else { + done++; + l = lastpp-pp; + } + if (l > 255) + return(-0xff); + else if (l > 0) { + len+=(l+1); + *(p++) = (uint8)l; + memcpy(p, pp, l); + *(p+l)='\0'; + k++; + XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p)); + p+=l; + } else { + XDPRINTF((1, 0, "component=%d, l=%d", k ,l)); + } + } + /* now as last element the volume */ + l=strlen(nw_volumes[dbe->nwpath.volume].sysname); + len+=(l+1); + *(p++) = (uint8)l; + memcpy(p, nw_volumes[dbe->nwpath.volume].sysname, l); + *(p+l)='\0'; + k++; + XDPRINTF((5, 0, "component=%d, path=`%s`", k ,p)); + + if (len > 400) + return(-0xff); /* we support only 'short' pathnames */ + + *components = k; + *cookieflags = (S_ISDIR(dbe->nwpath.statb.st_mode)) ? 0 : 1; + *cookie1 = 0; + *cookie2 = MAX_U32; /* no more cookies */ + return(len); + } + return(result); +} + static int nw_rename_file_dir(int namespace, NW_HPATH *nwps, uint8 *pathes_s, NW_HPATH *nwpd, uint8 *pathes_d, @@ -1201,7 +1513,7 @@ static int nw_modify_file_dir(int namespace, do_utime++; } if (do_utime) { - XDPRINTF((5, 0, "modify datetime 2=%2x,%2x,%2x,%2x", + XDPRINTF((5, 0, "modify datetime 2=%2x,%2x,%2x,%2x", (int) *datetime, (int) *(datetime+1), (int) *(datetime+2), @@ -1228,7 +1540,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) case 0x01 : /* open creat file or subdir */ { /* NW PATH STRUC */ - int opencreatmode = *(p+1); + int opencreatmode = (int) *(p+1); int attrib = (int) GET_16(p+2); /* LOW-HI */ uint32 infomask = GET_32(p+4); /* LOW-HI */ uint32 creatattrib = GET_32(p+8); @@ -1237,7 +1549,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) memcpy(&nwpathstruct, p+14, sizeof(nwpathstruct)); result = nw_open_creat_file_or_dir(namespace, opencreatmode, attrib, infomask, creatattrib, access_rights, - &nwpathstruct, p+21, responsedata); + &nwpathstruct, p+21, responsedata, task); } break; @@ -1256,6 +1568,12 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) case 0x03 : /* Search for File or DIR */ { + struct OUTPUT { + uint8 volume; + uint8 basehandle[4]; + uint8 sequence[4]; + uint8 reserved; + } *xdata= (struct OUTPUT*)responsedata; /* NW PATH STRUC */ int datastream = (int) *(p+1); int searchattrib = (int) GET_16(p+2); /* LOW-HI */ @@ -1265,10 +1583,21 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) uint32 sequence = GET_32(p+13); /* LOW-HI */ int len = *(p+17); uint8 *path = p+18; - result = nw_search_file_dir(namespace, datastream, - searchattrib, infomask, - volume, basehandle, sequence, - len, path, responsedata); + int count = 1; + int more_entries; + result = nw_search_file_dir(namespace, namespace /*datastream*/, + searchattrib, infomask, &count, + volume, basehandle, &sequence, + len, path, + responsedata+sizeof(struct OUTPUT), + &more_entries); + if (result > -1) { + xdata->volume = (uint8)volume; + U32_TO_32(basehandle, xdata->basehandle); + U32_TO_32(sequence, xdata->sequence); + xdata->reserved = (uint8) 0; + result+=sizeof(struct OUTPUT); + } } break; @@ -1290,7 +1619,10 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) case 0x06 : /* Obtain File or Subdir Info */ { - int destnamspace = (int) p+1; +#if 0 +static int code = 0; +#endif + int destnamspace = (int) *(p+1); int searchattrib = (int) GET_16(p+2); /* LOW-HI */ uint32 infomask = GET_32(p+4); /* LOW-HI */ NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8); @@ -1298,6 +1630,19 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) destnamspace, searchattrib, infomask, responsedata); +#if 0 + if (result < 0) { + /* Unix Client errormessages */ + /* there exist *NO* result to force client to use new */ + /* basehandles :-(( */ + /* most are -> IO/Error */ + /* -0x9c; -> no such file or dir */ + /* -0xfb; -> Protokoll Error */ + /* -0xff; -> no such file or dir */ + if (code < 0xff) result=-(++code); + else result=-0xfe; + } +#endif } break; @@ -1325,10 +1670,11 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) break; case 0x09 : /* Set short Dir Handle*/ - { - - - + { /* nw32client needs it */ + int desthandle = (int)*(p+2); + NW_HPATH *nwp = (NW_HPATH *)(p+4); + result = nw_set_short_dir_handle(namespace, desthandle, nwp, task); + /* NO REPLY Packet */ } break; @@ -1353,6 +1699,43 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) } break; + case 0x14 : /* Search for File or Subdir Set */ + /* SIMPLE IMPLEMENTATION, needs more work !!!! */ + { + struct OUTPUT { + uint8 volume; + uint8 basehandle[4]; + uint8 sequence[4]; + uint8 more_entries; /* NW4.1 (UNIX) says 0xff here */ + uint8 count[2]; /* count of entries */ + } *xdata= (struct OUTPUT*)responsedata; + int datastream = (int) *(p+1); + int searchattrib = (int) GET_16(p+2); /* LOW-HI */ + uint32 infomask = GET_32(p+4); /* LOW-HI */ + int count = (int)GET_16(p+8); + int volume = *(p+10); + uint32 basehandle = GET_32(p+11); /* LOW-HI */ + uint32 sequence = GET_32(p+15); /* LOW-HI */ + int len = *(p+19); + uint8 *path = p+20; + int more_entries; + result = nw_search_file_dir(namespace, namespace /*datastream*/, + searchattrib, infomask, &count, + volume, basehandle, &sequence, + len, path, + responsedata+sizeof(struct OUTPUT), + &more_entries); + if (result > -1) { + xdata->volume = (uint8)volume; + U32_TO_32(basehandle, xdata->basehandle); + U32_TO_32(sequence, xdata->sequence); + xdata->more_entries = (uint8) more_entries; + U16_TO_16(count, xdata->count); + result+=sizeof(struct OUTPUT); + } + } + break; + case 0x15 : /* Get Path String from short dir new */ { int dir_handle=(int) *(p+1); @@ -1410,14 +1793,48 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) } break; - case 0x1c : /* GetFullPathString new*/ - { + case 0x1c : /* GetFullPathString new*/ + { /* nw32 client needs it */ + /* SIMPLE IMPLEMENTATION, needs more work !!!! */ + int destnamspace = (int)*(p+1); + int cookieflags = (int)GET_16(p+2); + uint32 cookie1 = GET_32(p+4); + uint32 cookie2 = GET_32(p+8); + NW_HPATH *nwpathstruct = (NW_HPATH *)(p+12); + int components; + struct OUTPUT { + uint8 cookieflags[2]; /* 0 = DIR; 1 = FILE */ + uint8 cookie1[4]; + uint8 cookie2[4]; + uint8 pathsize[2]; /* complete components size */ + uint8 pathcount[2]; /* component counts */ + } *xdata= (struct OUTPUT*)responsedata; + result = nw_get_full_path_cookies(namespace, destnamspace, + nwpathstruct, + &cookieflags, &cookie1, &cookie2, &components, + responsedata+sizeof(struct OUTPUT)); + if (result > -1) { + U16_TO_16(cookieflags, xdata->cookieflags); + U32_TO_32(cookie1, xdata->cookie1); + U32_TO_32(cookie2, xdata->cookie2); + U16_TO_16(result, xdata->pathsize); + U16_TO_16(components, xdata->pathcount); + result+=sizeof(struct OUTPUT); + } } break; + case 0x1d : /* GetEffDirRights new */ { - + int destnamspace = (int) *(p+1); + int searchattrib = (int) GET_16(p+2); /* LOW-HI */ + uint32 infomask = GET_32(p+4); /* LOW-HI */ + NW_HPATH *nwpathstruct = (NW_HPATH *) (p+8); + result = nw_get_eff_rights(namespace, nwpathstruct, + destnamspace, + searchattrib, infomask, + responsedata); } break; @@ -1426,46 +1843,6 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) return(result); } -static void build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname) -{ - uint8 *ss=e->nwpath.fn; - int len=0; - int pf=0; - int is_ok=1; - int options=get_volume_options(e->nwpath.volume, 1); - for (; *ss; ss++){ - if (*ss == '.') { - if (pf++) { /* no 2. point */ - is_ok=0; - break; - } - len=0; - } else { - ++len; - if ((pf && len > 3) || len > 8) { - is_ok=0; - break; - } - if (!(options & VOL_OPTION_IGNCASE)){ - if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ - if (*ss >= 'A' && *ss <= 'Z') { - is_ok=0; - break; - } - } else { /* only upshift chars */ - if (*ss >= 'a' && *ss <= 'z') { - is_ok=0; - break; - } - } - } - } - } - if (is_ok) - strcpy(fname, e->nwpath.fn); - else - sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino); -} int get_namespace_dir_entry(int volume, uint32 basehandle, int namspace, uint8 *rdata) @@ -1484,7 +1861,7 @@ int get_namespace_dir_entry(int volume, uint32 basehandle, #else U32_TO_32(name_2_base(&(e->nwpath), NAME_DOS, 1), scif->searchsequence); #endif - build_dos_name(e, fname); + (void)build_dos_name(e, fname); if (S_ISDIR(e->nwpath.statb.st_mode)) { get_dos_dir_attrib(&(scif->u.d), &e->nwpath.statb, e->nwpath.volume, fname); diff --git a/namspace.h b/namspace.h index 4f82688..70adba3 100644 --- a/namspace.h +++ b/namspace.h @@ -1,4 +1,4 @@ -/* namspace.h 07-Feb-96 : NameSpace Services, mars_nwe */ +/* namspace.h 09-Nov-96 : NameSpace Services, mars_nwe */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -32,7 +32,11 @@ typedef struct { uint8 base[4]; /* Base or short Handle, handle is base[0] !! */ uint8 flag; /* 0=handle, 1=base, 0xff=not path nor handle */ uint8 components; /* nmbrs of pathes, components */ - uint8 pathes[1]; /* form len+name */ + uint8 pathes[1]; /* form len+name (like Pascal) */ + /* ATTENTION + * a pathlen of 0 means '..' (cd dir ..) !! + * first seen with Novell client32 + */ } NW_HPATH; typedef struct { @@ -65,10 +69,6 @@ typedef struct { #define INFO_MSK_DIR_ENTRY_INFO 0x00000400 #define INFO_MSK_RIGHTS_INFO 0x00000800 -/* File Attributes */ -#define FILE_ATTR_NORMAL 0x00000000 -#define FILE_ATTR_DIR 0x00000010 -#define FILE_ATTR_SHARE 0x00000080 /* Search Attributes */ #define W_SEARCH_ATTR_DIR 0x00008000 diff --git a/ncpserv.c b/ncpserv.c index 8bc641b..646fff2 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -1,4 +1,4 @@ -/* ncpserv.c 20-Mar-96 */ +/* ncpserv.c 01-Nov-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -119,34 +119,11 @@ static void write_to_nwserv(int what, int connection, int mode, static int open_ipx_sockets(void) { - struct t_bind bind; - ncp_fd=t_open("/dev/ipx", O_RDWR, NULL); - if (ncp_fd < 0) { - t_error("t_open !Ok"); + ncp_fd = open_ipx_socket(&my_addr, SOCK_NCP); + if (ncp_fd < 0) return(-1); - } - U16_TO_BE16(SOCK_NCP, my_addr.sock); /* NCP_SOCKET */ - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)&my_addr; - bind.qlen = 0; /* ever 0 */ - if (t_bind(ncp_fd, &bind, &bind) < 0){ - t_error("t_bind in open_ipx_sockets !OK"); - close(ncp_fd); - return(-1); - } #if USE_PERMANENT_OUT_SOCKET - ipx_out_fd=t_open("/dev/ipx", O_RDWR, NULL); - if (ipx_out_fd > -1) { - U16_TO_BE16(0, my_addr.sock); /* dynamic socket */ - if (t_bind(ipx_out_fd, &bind, &bind) < 0) { - if (nw_debug) t_error("2. t_bind in open_ipx_sockets !OK"); - t_close(ipx_out_fd); - ipx_out_fd = -1; - } - } else { - if (nw_debug) t_error("2. t_open !Ok"); - } + ipx_out_fd = open_ipx_socket(NULL, 0); #endif return(0); } @@ -479,6 +456,9 @@ static int handle_ctrl(void) if (data_len == sizeof(int)) { XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd->owndata.d.size)); +#if 1 + (void)send_own_reply(ipx_out_fd, 0, ipxd->owndata.h.sequence, &from_addr); +#endif switch (what) { case 0x5555 : /* clear_connection, from wdog process */ if (sizeof (int) == @@ -517,9 +497,14 @@ static void handle_ncp_request(void) XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr))); if ((type = GET_BE16(ncprequest->type)) == 0x2222 || type == 0x5555) { + int connection = (int)ncprequest->connection; XDPRINTF((10,0, "GOT 0x%x in NCPSERV connection=%d", type, connection)); - +#if 0 + ncp_response(0x9999, ncprequest->sequence, + connection, ncprequest->task, + 0x0, 0, 0); +#endif if ( connection > 0 && connection <= anz_connect) { CONNECTION *c = &(connections[connection-1]); @@ -537,7 +522,8 @@ static void handle_ncp_request(void) && !c->retry++) { /* perhaps nwconn is busy */ ncp_response(0x9999, ncprequest->sequence, - connection, 0, 0x0, 0, 0); + connection, ncprequest->task, + 0x0, 0, 0); XDPRINTF((2, 0, "Send Request being serviced to connection:%d", connection)); return; } @@ -561,9 +547,7 @@ static void handle_ncp_request(void) if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence) #endif { -#if 1 clear_connection(connection); -#endif ncp_response(0x3333, ncprequest->sequence, connection, @@ -589,6 +573,7 @@ static void handle_ncp_request(void) type, ncprequest->connection, anz_connect)); } + if (type == 0x5555 || (type == 0x2222 && ncprequest->function == 0x19)) { compl = 0; cstat = 0; @@ -598,7 +583,7 @@ static void handle_ncp_request(void) } ncp_response(0x3333, ncprequest->sequence, ncprequest->connection, - (type== 0x5555) ? 0 : 1, /* task */ + (type== 0x5555) ? 0 : ncprequest->task, /* task */ compl, /* completition */ cstat, /* conn status */ 0); @@ -688,6 +673,7 @@ int main(int argc, char *argv[]) #ifdef LINUX set_emu_tli(); #endif + if (open_ipx_sockets()) { errorp(1, "open_ipx_sockets", NULL); return(1); diff --git a/net.h b/net.h index 88b75d0..25d9cd2 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -/* net.h 03-May-96 */ +/* net.h 25-Oct-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -82,23 +82,21 @@ extern int errno; *( (uint8*) (b) ) = *( ((uint8*) (&a)) +1); \ *( ((uint8*) (b)) +1) = *( (uint8*) (&a)); } -#if 0 -/* I don't know anymore why I did coded it in this form */ -#define X_U32_TO_BE32(u, ar) { uint32 a= (uint32)(u); uint8 *b= ((uint8*)(ar))+3; \ - *b-- = (uint8)a; a >>= 8; \ - *b-- = (uint8)a; a >>= 8; \ - *b-- = (uint8)a; a >>= 8; \ - *b = (uint8)a; } -#else #define X_U32_TO_BE32(u, b) { uint32 a=(uint32)(u); \ *( (uint8*) (b)) = *( ((uint8*) (&a))+3); \ *( ((uint8*) (b)) +1) = *( ((uint8*) (&a))+2); \ *( ((uint8*) (b)) +2) = *( ((uint8*) (&a))+1); \ *( ((uint8*) (b)) +3) = *( (uint8*) (&a)); } -#endif -#define X_U16_TO_16(u, b) { uint16 a=(uint16)(u); memcpy(b, &a, 2); } -#define X_U32_TO_32(u, b) { uint32 a=(uint32)(u); memcpy(b, &a, 4); } +#define X_U16_TO_16(u, b) { uint16 a=(uint16)(u); \ + ((uint8*)b)[0] = ((uint8*)&a)[0]; \ + ((uint8*)b)[1] = ((uint8*)&a)[1]; } + +#define X_U32_TO_32(u, b) { uint32 a=(uint32)(u); \ + ((uint8*)b)[0] = ((uint8*)&a)[0]; \ + ((uint8*)b)[1] = ((uint8*)&a)[1]; \ + ((uint8*)b)[2] = ((uint8*)&a)[2]; \ + ((uint8*)b)[3] = ((uint8*)&a)[3]; } #define GET_BE16(b) ( (int) *(((uint8*)(b))+1) \ | ( ( (int) *( (uint8*)(b) ) << 8) ) ) @@ -236,10 +234,21 @@ extern int errno; # define MAX_NW_SERVERS MAX_NW_ROUTES #endif +#ifndef HANDLE_ALL_SAP_TYPS +# define HANDLE_ALL_SAP_TYPS 0 +#endif + #if IPX_DATA_GR_546 -# define IPX_MAX_DATA 1058 +# if IPX_DATA_GR_546 == 2 +# define IPX_MAX_DATA 1470 +# define RW_BUFFERSIZE 1444 +# else +# define IPX_MAX_DATA 1058 +# define RW_BUFFERSIZE 1024 +# endif #else -# define IPX_MAX_DATA 546 +# define IPX_MAX_DATA 546 +# define RW_BUFFERSIZE 512 #endif #ifndef SOCK_EXTERN @@ -366,15 +375,22 @@ typedef union { uint8 function; /* Function */ } ncprequest; struct S_OWN_DATA { - uint8 type[2]; /* 0xeeee */ - uint8 sequence; - uint8 connection; + struct { + uint8 type[2]; /* 0xeeee */ + uint8 sequence; + uint8 reserved; /* its good for alignement */ + } h; /* header */ struct { int size; /* size of next two entries */ int function; uint8 data[1]; } d; } owndata; + struct S_OWN_REPLY { + uint8 type[2]; /* 0xefef */ + uint8 sequence; + uint8 result; /* perhaps we need it */ + } ownreply; char data[IPX_MAX_DATA]; } IPX_DATA; @@ -389,8 +405,7 @@ typedef struct S_DIAGRESP DIAGRESP; typedef struct S_NCPRESPONSE NCPRESPONSE; typedef struct S_NCPREQUEST NCPREQUEST; typedef struct S_OWN_DATA OWN_DATA; - -#define OWN_DATA_IPX_BASE_SIZE 8 +typedef struct S_OWN_REPLY OWN_REPLY; /* SOCKETS */ #define SOCK_AUTO 0x0000 /* Autobound Socket */ diff --git a/net1.c b/net1.c index e910112..07c4854 100644 --- a/net1.c +++ b/net1.c @@ -1,4 +1,4 @@ -/* net1.c, 20-Mar-96 */ +/* net1.c, 26-Oct-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -19,6 +19,9 @@ #include "net.h" +#define MAX_SEND_TRIES 5 +#define MAX_WAIT_MSEC 1000 /* 1 sec should be enough */ + #if HAVE_TLI void print_t_info(struct t_info *t) { @@ -147,12 +150,36 @@ void ipx_addr_to_adr(char *s, ipxAddr_t *p) (int)p->sock[1]); } +int open_ipx_socket(ipxAddr_t *addr, int sock_nr) +{ + struct t_bind bind; + ipxAddr_t addr_buff; + int fd=t_open("/dev/ipx", O_RDWR, NULL); + if (fd < 0) { + t_error("t_open !Ok"); + return(-1); + } + if (NULL == addr) + addr = &addr_buff; + memset(addr, 0, sizeof(ipxAddr_t)); + U16_TO_BE16(sock_nr, addr->sock); + bind.addr.len = sizeof(ipxAddr_t); + bind.addr.maxlen = sizeof(ipxAddr_t); + bind.addr.buf = (char*)addr; + bind.qlen = 0; + if (t_bind(fd, &bind, &bind) < 0){ + t_error("t_bind,open_ipx_socket"); + t_close(fd); + return(-1); + } + return(fd); +} -int send_ipx_data(int fdx, int pack_typ, +int send_ipx_data(int fd, int pack_typ, int data_len, char *data, ipxAddr_t *to_addr, char *comment) { - int fd=fdx; + int fd_is_dyna=0; int result=0; struct t_unitdata ud; uint8 ipx_pack_typ = (uint8) pack_typ; @@ -168,34 +195,125 @@ int send_ipx_data(int fdx, int pack_typ, if (comment != NULL) XDPRINTF((2,0,"%s TO: ", comment)); if (nw_debug > 1) print_ipx_addr(to_addr); if (fd < 0) { - struct t_bind bind; - ipxAddr_t addr; - fd=t_open("/dev/ipx", O_RDWR, NULL); - if (fd < 0) { - t_error("t_open !Ok"); + if ((fd=open_ipx_socket(NULL, 0)) < 0) return(-1); - } - memset(&addr,0, sizeof(ipxAddr_t)); - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)&addr; - bind.qlen = 0; /* ever */ - if (t_bind(fd, &bind, &bind) < 0){ - t_error("t_bind in send_ipx_data"); - t_close(fd); - return(-1); - } + fd_is_dyna++; } if ((result=t_sndudata(fd, &ud)) < 0){ if (nw_debug > 1) t_error("t_sndudata !OK"); } - if (fdx < 0 && fd > -1) { + if (fd_is_dyna) { t_unbind(fd); t_close(fd); } return(result); } +int receive_ipx_data(int fd, int *pack_typ, IPX_DATA *d, + ipxAddr_t *fromaddr, int waitmsec) +{ + int result=-1; + if (waitmsec) { + struct pollfd polls[1]; + polls[0].fd = fd; + polls[0].events = POLLIN|POLLPRI; + polls[0].revents = 0; + if (1 == poll(polls, 1, waitmsec)) + waitmsec=0; + } + if (!waitmsec) { + struct t_unitdata ud; + uint8 ipx_pack_typ; + int flags = 0; + ud.opt.len = sizeof(ipx_pack_typ); + ud.opt.maxlen = sizeof(ipx_pack_typ); + ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual typ */ + + ud.addr.len = sizeof(ipxAddr_t); + ud.addr.maxlen = sizeof(ipxAddr_t); + + ud.addr.buf = (char*)fromaddr; + ud.udata.len = IPX_MAX_DATA; + ud.udata.maxlen = IPX_MAX_DATA; + ud.udata.buf = (char*)d; + if (t_rcvudata(fd, &ud, &flags) < 0){ + struct t_uderr uderr; + ipxAddr_t erradr; + uint8 err_pack_typ; + uderr.addr.len = sizeof(ipxAddr_t); + uderr.addr.maxlen = sizeof(ipxAddr_t); + uderr.addr.buf = (char*)&erradr; + uderr.opt.len = sizeof(err_pack_typ); + uderr.opt.maxlen = sizeof(err_pack_typ); + uderr.opt.buf = (char*)&err_pack_typ; /* get actual typ */ + ud.addr.buf = (char*)&fromaddr; + t_rcvuderr(fd, &uderr); + XDPRINTF((2, 0, "Error from %s, Code = 0x%lx", visable_ipx_adr(&erradr), uderr.error)); + if (nw_debug) + t_error("t_rcvudata !OK"); + result = -1; + } else { + if (pack_typ) + *pack_typ=(int)ipx_pack_typ; + result=ud.udata.len; + } + } + return(result); +} + +int send_own_data(int fd, IPX_DATA *d, ipxAddr_t *toaddr) +/* returns < 0 if senderror or functionresultcode > = 0 */ +{ +static int lastsequence=0; + int result = -1; + int tries = 0; + int sendsize = d->owndata.d.size+sizeof(d->owndata.d.size)+ + sizeof(d->owndata.h); + d->owndata.h.type[0] = 0xee; + d->owndata.h.type[1] = 0xee; + d->owndata.h.sequence = (uint8) ++lastsequence; + d->owndata.h.reserved = 0; + + while (tries++ < MAX_SEND_TRIES && result < 0) { + result=send_ipx_data(fd, 17, sendsize, (char*)d, + toaddr, "send_own_data"); + + if (result > -1) { + int packet_typ; + IPX_DATA ipxd; + ipxAddr_t fromaddr; + result=receive_ipx_data(fd, &packet_typ, &ipxd, &fromaddr, + MAX_WAIT_MSEC); + XDPRINTF((2, 0, "receive_ipx_data, result=%d, typ=0x%x%x, sequence=%d", + result, + (int)ipxd.ownreply.type[0], + (int)ipxd.ownreply.type[1], + (int)ipxd.ownreply.sequence )); + if (sizeof(OWN_REPLY) == result && + ipxd.ownreply.type[0] == 0xef && + ipxd.ownreply.type[1] == 0xef && + /* !memcmp(&fromaddr, toaddr, sizeof(ipxAddr_t)) && */ + ipxd.ownreply.sequence == d->owndata.h.sequence) { + result = (int)ipxd.ownreply.result; + } else + result=-1; + } + } /* while */ + return(result); +} + +int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr) +{ + IPX_DATA ipxd; + IPX_DATA *d=&ipxd; + d->ownreply.type[0] = 0xef; + d->ownreply.type[1] = 0xef; + d->ownreply.sequence = (uint8) sequence; + d->ownreply.result = result; + return(send_ipx_data(fd, 17, sizeof(OWN_REPLY), + (char*)d, toaddr, "send_own_reply")); +} + #if 0 int get_ipx_addr(ipxAddr_t *addr) { diff --git a/net1.h b/net1.h index 5fa3465..cd999a1 100644 --- a/net1.h +++ b/net1.h @@ -1,4 +1,4 @@ -/* net1.h 20-Mar-96 */ +/* net1.h 25-Oct-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -34,10 +34,18 @@ extern void print_sip_data(SIP *sip); extern void adr_to_ipx_addr(ipxAddr_t *p, char *s); extern void ipx_addr_to_adr(char *s, ipxAddr_t *p); +extern int open_ipx_socket(ipxAddr_t *addr, int sock_nr); + extern int send_ipx_data(int fd, int pack_typ, int data_len, char *data, ipxAddr_t *to_addr, char *comment); +extern int receive_ipx_data(int fd, int *pack_typ, IPX_DATA *d, + ipxAddr_t *fromaddr, int waitmsec); + +extern int send_own_data(int fd, IPX_DATA *d, ipxAddr_t *toaddr); +extern int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr); + extern int get_ipx_addr(ipxAddr_t *addr); #endif diff --git a/nwbind.c b/nwbind.c index 5464f3f..888c9b3 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "04-Oct-96" +#define REVISION_DATE "01-Nov-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -64,44 +64,6 @@ static void write_to_nwserv(int what, int connection, int mode, #define nwserv_down_server() \ write_to_nwserv(0xffff, 0, 0, NULL, 0) -static int open_ipx_sockets(void) -{ - struct t_bind bind; - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)&my_addr; - bind.qlen = 0; /* immer */ -#if 0 - ncp_fd=t_open("/dev/ipx", O_RDWR, NULL); - if (ncp_fd < 0) { - t_error("t_open !Ok"); - return(-1); - } - U16_TO_BE16(SOCK_BINDERY, my_addr.sock); - if (t_bind(ncp_fd, &bind, &bind) < 0){ - t_error("t_bind in open_ipx_sockets !OK"); - close(ncp_fd); - return(-1); - } -#endif - -#if USE_PERMANENT_OUT_SOCKET - ipx_out_fd=t_open("/dev/ipx", O_RDWR, NULL); - if (ipx_out_fd > -1) { - U16_TO_BE16(SOCK_AUTO, my_addr.sock); /* dynamic socket */ - if (t_bind(ipx_out_fd, &bind, &bind) < 0) { - if (nw_debug) t_error("2. t_bind in open_ipx_sockets !OK"); - t_close(ipx_out_fd); - ipx_out_fd = -1; - } - } else { - if (nw_debug) t_error("2. t_open !Ok"); - } - -#endif - return(0); -} - typedef struct { ipxAddr_t client_adr; /* address remote client */ uint32 object_id; /* logged object */ @@ -1280,6 +1242,7 @@ static void handle_fxx(int gelen, int func) U16_TO_BE16(0x3333, ncpresponse->type); ncpresponse->sequence = ncprequest->sequence; + ncpresponse->task = ncprequest->task; ncpresponse->connection = ncprequest->connection; ncpresponse->reserved = 0; ncpresponse->completition = completition; @@ -1352,7 +1315,7 @@ static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size) return(size); } -static void handle_ctrl(void) +static void handle_ctrl() /* reads packets from nwserv/ncpserv */ { IPX_DATA ipxd; @@ -1364,8 +1327,10 @@ static void handle_ctrl(void) if (data_len == sizeof(int)) { XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd.owndata.d.size)); - switch (what) { + (void)send_own_reply(ipx_out_fd, 0, ipxd.owndata.h.sequence, &from_addr); + + switch (what) { case 0x2222 : /* insert connection */ if (sizeof (int) == xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) { @@ -1409,9 +1374,9 @@ static void handle_ctrl(void) if (sizeof(int) == data_len && conn == what) sent_down_message(); break; - default : break; } /* switch */ + } else { errorp(1, "handle_ctrl", "wrong data len=%d", data_len); } @@ -1461,11 +1426,9 @@ int main(int argc, char *argv[]) set_emu_tli(); #endif - if (open_ipx_sockets()) { - errorp(1, "open_ipx_sockets", NULL); - exit(1); - } - +#if USE_PERMANENT_OUT_SOCKET + ipx_out_fd=open_ipx_socket(NULL, 0); +#endif XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s", (ipx_out_fd > -1) ? "enabled" : "disabled")); @@ -1509,12 +1472,11 @@ int main(int argc, char *argv[]) && IPXCMPNODE(from_addr.node, my_addr.node) && IPXCMPNET (from_addr.net, my_addr.net)) { /* comes from nwserv, i hope :) */ - handle_ctrl(); - } else { - XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x", - (int) GET_BE16(ncprequest->type), (int) ncprequest->function)); + XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x from %s", + (int) GET_BE16(ncprequest->type), + (int) ncprequest->function, visable_ipx_adr(&from_addr) )); } } if (got_sig == SIGHUP) { diff --git a/nwconn.c b/nwconn.c index ca08453..8785529 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 03-Oct-96 */ +/* nwconn.c 06-Nov-96 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -47,6 +47,7 @@ static uint8 readbuff[IPX_MAX_DATA]; static uint8 saved_readbuff[IPX_MAX_DATA]; static int saved_sequence=-1; +static int rw_buffer_size = 512; /* default */ static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff; static uint8 *requestdata = readbuff + sizeof(NCPREQUEST); @@ -56,10 +57,11 @@ static int sock_echo =-1; static int req_printed=0; -static int ncp_response(int sequence, +static int ncp_response(int sequence, int task, int completition, int data_len) { ncpresponse->sequence = (uint8) sequence; + ncpresponse->task = (uint8) task; ncpresponse->completition = (uint8) completition; ncpresponse->reserved = (uint8) 0; last_sequence = sequence; @@ -326,7 +328,7 @@ static int handle_ncp_serv(void) xdata->volume = (uint8) result; data_len = 1; } else completition = (uint8) -result; - } else if (*p == 0x6){ /* Get Volume Name von 0 .. 31 */ + } else if (*p == 0x6){ /* Get Volume Name from 0 .. 31 */ /******** Get Volume Name ***************/ struct XDATA { uint8 namelen; @@ -447,7 +449,7 @@ static int handle_ncp_serv(void) } } data_len = sizeof(struct XDATA); - XDPRINTF((5,0,"GIVE VOLUME INFO von :%s:", xdata->name)); + XDPRINTF((5,0,"GIVE VOLUME INFO from :%s:", xdata->name)); result = 0; } } @@ -855,7 +857,7 @@ static int handle_ncp_serv(void) uint8 size[4]; uint8 weisnicht[2]; /* lock timeout ??? */ } *input = (struct INPUT *)ncprequest; - int fhandle = GET_BE32(input->fhandle); + int fhandle = GET_BE32 (input->fhandle); int offset = GET_BE32(input->offset); int size = GET_BE32(input->size); completition = (uint8)(-nw_lock_datei(fhandle, @@ -865,17 +867,13 @@ static int handle_ncp_serv(void) break; case 0x21 : { /* Negotiate Buffer Size, Packetsize */ - int wantsize = GET_BE16((uint8*)requestdata); uint8 *getsize=responsedata; -#if !IPX_DATA_GR_546 - wantsize = min(0x200, wantsize); -#else - wantsize = min(0x400, wantsize); -#endif - U16_TO_BE16(wantsize, getsize); + rw_buffer_size = min(RW_BUFFERSIZE, + (int) (GET_BE16((uint8*)requestdata))); + U16_TO_BE16(rw_buffer_size, getsize); data_len = 2; XDPRINTF((5,0, "Negotiate Buffer size = 0x%04x,(%d)", - (int) wantsize, (int) wantsize)); + (int) rw_buffer_size, (int) rw_buffer_size)); } break; @@ -931,7 +929,7 @@ static int handle_ncp_serv(void) struct INPUT { uint8 header[7]; /* Requestheader */ uint8 volume; /* Volume ID */ - uint8 dir_id[2]; /* von File Search Init */ + uint8 dir_id[2]; /* from File Search Init */ uint8 searchsequence[2]; /* sequence FFFF = first entry */ uint8 search_attrib; /* Attribute */ /* 0 none, @@ -1024,7 +1022,7 @@ static int handle_ncp_serv(void) input->data, input->len, &(xdata->fileinfo), (int)input->attrib, - 0x1, 0); + 0x1, 0, (int)(ncprequest->task)); if (fhandle > -1){ U32_TO_BE32(fhandle, xdata->fhandle); @@ -1075,7 +1073,8 @@ static int handle_ncp_serv(void) &(xdata->fileinfo), (int)input->attribute, 0, - (function==0x43) ? 1 : 2); + (function==0x43) ? 1 : 2, + (int)(ncprequest->task)); if (fhandle > -1){ data_len = sizeof(struct XDATA); U32_TO_BE32(fhandle, xdata->fhandle); @@ -1189,7 +1188,13 @@ static int handle_ncp_serv(void) int max_size = GET_BE16(input->max_size); off_t offset = GET_BE32(input->offset); int zusatz = (offset & 1) ? 1 : 0; - int size = nw_read_datei(fhandle, + int size; + if (max_size > rw_buffer_size) { + XDPRINTF((1,0, "wanted read=%d byte > %d", + max_size, rw_buffer_size)); + size = -0x88; /* we say wrong filehandle */ + } else + size = nw_read_datei(fhandle, xdata->data+zusatz, max_size, offset); @@ -1296,7 +1301,8 @@ static int handle_ncp_serv(void) input->data, input->len, &(xdata->fileinfo), (int)input->attrib, - (int)input->access, 0); + (int)input->access, 0, + (int)(ncprequest->task)); if (fhandle > -1){ U32_TO_BE32(fhandle, xdata->fhandle); @@ -1336,6 +1342,7 @@ static int handle_ncp_serv(void) #ifdef _MAR_TESTS_XX case 0x5f : { /* ????????????? UNIX Client */ + /* a 4.1 Server also do not know this call */ struct INPUT { uint8 header[7]; /* Requestheader */ uint8 unknown[4]; /* 0x10, 0,0,0 */ @@ -1418,10 +1425,7 @@ static int handle_ncp_serv(void) XDPRINTF((0,1, NULL)); } } -#if 0 - ncpresponse->task = ncprequest->task; -#endif - ncp_response(ncprequest->sequence, completition, data_len); + ncp_response(ncprequest->sequence, ncprequest->task, completition, data_len); nw_debug = org_nw_debug; return(0); } @@ -1501,7 +1505,7 @@ static void handle_after_bind() break; default : completition = 0xfb; } /* switch */ - ncp_response(ncprequest->sequence, completition, data_len); + ncp_response(ncprequest->sequence, ncprequest->task, completition, data_len); } extern int t_errno; @@ -1617,6 +1621,9 @@ int main(int argc, char **argv) */ ncpresponse->connect_status = (uint8) 0; + /* new: 01-Nov-96 */ + ncpresponse->task = ncprequest->task; + if (fl_get_int) { if (fl_get_int == 1) get_new_debug(); else if (fl_get_int < 0) break; @@ -1639,8 +1646,9 @@ int main(int argc, char **argv) if (data_len) memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len); ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status; - ncp_response((int)(ncprequest->sequence), - (int)(ncprequest->function), data_len); + ncp_response(ncprequest->sequence, + ncprequest->task, + ncprequest->function, data_len); } saved_sequence = -1; } else { /* this calls I must handle, it is a request */ diff --git a/nwdbm.c b/nwdbm.c index bcffc0c..39e02c6 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1247,7 +1247,7 @@ int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr) } } XDPRINTF((1, 0, "No access for Station %s", visable_ipx_adr(client_adr))); - return(-0xff); /* perhaps I find a better result later */ + return(-0xdb); /* unauthorized login station */ } #if 0 diff --git a/nwfile.c b/nwfile.c index afb2aab..34b54eb 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 29-Sep-96 */ +/* nwfile.c 04-Nov-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -39,11 +39,12 @@ void sig_bus_mmap(int rsig) #endif static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN]; +#define HOFFS 0 static int anz_fhandles=0; -static int new_file_handle(uint8 *unixname) +static int new_file_handle(uint8 *unixname, int task) { - int rethandle = -1; + int rethandle = HOFFS -1; FILE_HANDLE *fh=NULL; while (++rethandle < anz_fhandles) { FILE_HANDLE *fh=&(file_handles[rethandle]); @@ -62,6 +63,7 @@ static int new_file_handle(uint8 *unixname) } } /* init handle */ + fh->task = task; fh->fd = -2; fh->offd = 0L; fh->tmodi = 0L; @@ -76,7 +78,7 @@ static int new_file_handle(uint8 *unixname) static int free_file_handle(int fhandle) { int result=-0x88; - if (fhandle > 0 && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE_COMMAND) { @@ -105,7 +107,7 @@ static int free_file_handle(int fhandle) if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* was last */ anz_fhandles--; - while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1 + while (anz_fhandles > HOFFS && file_handles[anz_fhandles-1].fd == -1 && !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) anz_fhandles--; } @@ -116,14 +118,28 @@ static int free_file_handle(int fhandle) return(result); /* wrong filehandle */ } -void init_file_module(void) +void init_file_module(int task) +/* + * if task == -1 all handles will be free'd + * else only handles of the task will be free'd + */ { - int k = 0; - while (k++ < anz_fhandles) free_file_handle(k); - anz_fhandles = 0; + int k = HOFFS; + if (task < 0) { + while (k++ < anz_fhandles) + free_file_handle(k); + anz_fhandles = HOFFS; + } else { + /* I hope next is ok, added 20-Oct-96 ( 0.98.pl5 ) */ + while (k++ < anz_fhandles) { + FILE_HANDLE *fh=&(file_handles[k-1]); + if (fh->task == task) { + free_file_handle(k); + } + } + } } - static int xsetegid(gid_t gid) { int result = -1; @@ -141,7 +157,7 @@ static int xsetegid(gid_t gid) } int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, - int attrib, int access, int creatmode) + int attrib, int access, int creatmode, int task) /* * creatmode: 0 = open * | 1 = creat (ever) @@ -152,8 +168,11 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, * * access: 0x1=read, * 0x2=write, - * 0x4=deny read, -> F_WRLCK - * 0x8=deny write -> F_RDLCK + * 0x4=deny read, -> F_WRLCK, no other process can make + * a read or write lock + * can only be used if file is open for writing + * 0x8=deny write -> F_RDLCK, no other process can make a writelock + * can only be used if file is open for reading * 0x10=SH_COMPAT * * 0x09 (O_RDONLY | O_DENYWRITE); @@ -167,9 +186,9 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, * */ { - int fhandle = new_file_handle(unixname); - int dowrite = (access & 2) || creatmode; - if (fhandle > 0){ + int fhandle = new_file_handle(unixname, task); + int dowrite = ((access & 2) || creatmode) ? 1 : 0; + if (fhandle > HOFFS){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); int completition = 0; /* first ok */ int voloptions = get_volume_options(volume, 1); @@ -188,9 +207,18 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, if (creatmode & 2) { XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->fname)); completition = -0x85; /* No Priv */ - } else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) ) - completition = (creatmode) ? -0x84 : -0x94; - else if (!(acc & R_OK) && !(creatmode & 0x8) ) + } else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) ) { + if (!S_ISFIFO(stbuff->st_mode)) { + if (entry8_flags&2 && (acc & R_OK)) { + /* we use strange compatibility modus */ + dowrite=0; + XDPRINTF((1, 0, "Uses strange open comp. mode for file `%s`", + fh->fname)); + } else + completition = (creatmode) ? -0x84 : -0x94; + } else + completition = (creatmode) ? -0x84 : -0x94; + } else if (!(acc & R_OK) && !(creatmode & 0x8) ) completition = -0x93; } else if (acc & X_OK) { /* special Handling for PIPE commands */ @@ -260,6 +288,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, if (!dowrite) stbuff->st_size = 0x7fff0000 | (rand() & 0xffff); (void)time(&(stbuff->st_mtime)); + stbuff->st_atime = stbuff->st_mtime; if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; if (did_grpchange) @@ -301,18 +330,18 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, stat(fh->fname, stbuff); } } else { - /* 'normal' open of file */ + /* ======== 'normal' open of file ================ */ int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY; if (S_ISFIFO(stbuff->st_mode)){ acm |= O_NONBLOCK; fh->fh_flags |= FH_IS_PIPE; if (!dowrite) stbuff->st_size = 0x7fffffff; (void)time(&(stbuff->st_mtime)); + stbuff->st_atime = stbuff->st_mtime; } fh->fd = open(fh->fname, acm); - XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d", - attrib,access, fh->fname, fhandle)); - fh->offd = 0L; + XDPRINTF((5,0, "OPEN FILE:fd=%d, attrib:0x%x, access:0x%x, fh->fname:%s:fhandle=%d", + fh->fd, attrib, access, fh->fname, fhandle)); if (fh->fd < 0) completition = dowrite ? -0x94 : -0x93; } @@ -321,9 +350,23 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, if (!(fh->fh_flags & FH_IS_PIPE)) { /* Not a PIPE */ if ((access & 0x4) || (access & 0x8)) { + /* we use file sharing */ struct flock flockd; - int result; - flockd.l_type = (access & 0x8) ? F_RDLCK : F_WRLCK; + 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; @@ -373,7 +416,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) { - if (fhandle > 0 && (--fhandle < anz_fhandles) ) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles) ) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { if (!(fh->fh_flags & FH_IS_READONLY)) { @@ -389,7 +432,7 @@ int nw_close_datei(int fhandle, int reset_reuse) { XDPRINTF((5, 0, "nw_close_datei handle=%d, anz_fhandles", fhandle, anz_fhandles)); - if (fhandle > 0 && (fhandle <= anz_fhandles)) { + if (fhandle > HOFFS && (fhandle <= anz_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)) { @@ -434,7 +477,7 @@ int nw_close_datei(int fhandle, int reset_reuse) uint8 *file_get_unix_name(int fhandle) { - if (fhandle > 0 && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { return((uint8*)file_handles[fhandle].fname); } return(NULL); @@ -455,7 +498,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite) int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) { - if (fhandle > 0 && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fh_flags & FH_IS_PIPE_COMMAND) open_pipe_command(fh, 0); @@ -519,7 +562,7 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) int nw_seek_datei(int fhandle, int modus) { - if (fhandle > 0 && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ @@ -541,7 +584,7 @@ int nw_seek_datei(int fhandle, int modus) int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) { - if (fhandle > 0 && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fh_flags & FH_IS_PIPE_COMMAND) open_pipe_command(fh, 1); @@ -584,19 +627,19 @@ int nw_server_copy(int qfhandle, uint32 qoffset, int zfhandle, uint32 zoffset, uint32 size) { - if (qfhandle > 0 && (--qfhandle < anz_fhandles) - && zfhandle > 0 && (--zfhandle < anz_fhandles) ) { + if (qfhandle > HOFFS && (--qfhandle < anz_fhandles) + && zfhandle > HOFFS && (--zfhandle < anz_fhandles) ) { FILE_HANDLE *fhq=&(file_handles[qfhandle]); FILE_HANDLE *fhz=&(file_handles[zfhandle]); int retsize = -1; if (fhq->fd > -1 && fhz->fd > -1) { - char buff[2048]; + char buff[4096]; int wsize; if (fhz->fh_flags & FH_IS_READONLY) return(-0x94); if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { retsize = 0; - while (size && !retsize) { + while (size) { int xsize = read(fhq->fd, buff, min(size, (uint32)sizeof(buff))); if (xsize > 0){ if ((wsize =write(fhz->fd, buff, xsize)) != xsize) { @@ -614,19 +657,16 @@ int nw_server_copy(int qfhandle, uint32 qoffset, } fhq->offd = -1L; fhz->offd = -1L; -/* - if (!retsize) (retsize=fhz->offd=lseek(fhz->fd, 0L, SEEK_END)); -*/ return(retsize); } } - return(- 0x88); /* wrong filehandle */ + return(-0x88); /* wrong filehandle */ } int nw_lock_datei(int fhandle, int offset, int size, int do_lock) { - if (fhandle > 0 && (--fhandle < anz_fhandles)) { + if (fhandle > HOFFS && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { struct flock flockd; @@ -642,7 +682,6 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock) 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) return(0); else return(-0x21); /* LOCK Violation */ } else if (fh->fd == -3) return(0); diff --git a/nwfile.h b/nwfile.h index f0d21b8..1246697 100644 --- a/nwfile.h +++ b/nwfile.h @@ -1,9 +1,10 @@ -/* nwfile.h 11-May-96 */ +/* nwfile.h 19-Oct-96 */ #ifndef _NWFILE_H_ #define _NWFILE_H_ #include "nwqueue.h" typedef struct { + int task; /* for which task */ int fd; /* filehandle from system open/creat */ long offd; /* actual file offset */ #if USE_MMAP @@ -26,11 +27,11 @@ typedef struct { extern void sig_bus_mmap(int rsig); -extern void init_file_module(void); +extern void init_file_module(int task); extern int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, - int attrib, int access, int creatmode); + int attrib, int access, int creatmode, int task); extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit); diff --git a/nwqueue.c b/nwqueue.c index ce614bb..54a88f6 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -1,4 +1,4 @@ -/* nwconn.c 29-Sep-96 */ +/* nwconn.c 19-Oct-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -278,7 +278,7 @@ static int create_queue_file(uint8 *job_file_name, if (result > -1) { struct stat stbuff; result=file_creat_open(result, (uint8*)unixname, - &stbuff, 0x6, 0x6, 1|4|8); + &stbuff, 0x6, 0x6, 1|4|8, 0); if (result > -1) { chown(unixname, act_uid, act_gid); chmod(unixname, 0660); diff --git a/nwroute.c b/nwroute.c index 9d48b1f..cd419ce 100644 --- a/nwroute.c +++ b/nwroute.c @@ -1,4 +1,4 @@ -/* nwroute.c 12-May-96 */ +/* nwroute.c 28-Oct-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -438,9 +438,9 @@ static void send_sap_to_addr(int entry, int hops, int ticks, memset(&ipx_data, 0, sizeof(ipx_data.sip)); strcpy((char*)ipx_data.sip.server_name, nw->name); memcpy(&ipx_data.sip.server_adr, &nw->addr, sizeof(ipxAddr_t)); - XDPRINTF((4, 0, "%s SERVER=%s, typ=0x%x, ticks=%d, hops=%d", + XDPRINTF((4, 0, "%s SERVER=%s, typ=0x%x, ticks=%d, hops=%d, sock=0x%x", (respond_typ==4) ? "NEAREST" : "GENERAL", nw->name, - nw->typ, ticks, hops)); + nw->typ, ticks, hops, (int)GET_BE16(nw->addr.sock))); U16_TO_BE16(respond_typ, ipx_data.sip.response_type); U16_TO_BE16(nw->typ, ipx_data.sip.server_type); U16_TO_BE16(hops, ipx_data.sip.intermediate_networks); @@ -529,16 +529,34 @@ static void send_sap_broadcast(int mode) } } -static FILE *open_route_info_fn(int force) +static FILE *open_route_info_fn(int force, FILE *ff, int section) { static int tacs=0; FILE *f=NULL; + if (section>1 && !(print_route_mode&2)) + return(ff); if (print_route_tac > 0) { if (!tacs || force) { - if (NULL != (f=fopen(pr_route_info_fn, - (print_route_mode) ? "w" : "a"))) { - tacs = print_route_tac-1; - } else print_route_tac=0; + char fnbuf[300]; + char *fn; + if (print_route_mode&2) { + sprintf(fnbuf, "%s.%d", pr_route_info_fn, section); + fn = fnbuf; + } else { + fn=pr_route_info_fn; + } + f=fopen(fn, (print_route_mode&0x1) ? "w" : "a"); + if (section == 1) { + if (NULL != f) + tacs = print_route_tac-1; + else + print_route_tac=0; + } else { + if (NULL != f) + fclose(ff); + else + f = ff; /* we use old file */ + } } else tacs--; } return(f); @@ -546,13 +564,14 @@ static FILE *open_route_info_fn(int force) void print_routing_info(int force) { - FILE *f= open_route_info_fn(force); + FILE *f= open_route_info_fn(force, NULL, 1); if (f) { int k=-1; + int i; time_t xtime; time(&xtime); fprintf(f, "%s", ctime(&xtime) ); - fprintf(f, "<--------- Devices ---------------->\n"); + fprintf(f, "<--------- %d Devices ---------------->\n", anz_net_devices); fprintf(f, "%-15s %-15s %5s Network Status\n", "DevName", "Frame", "Ticks"); while (++k < anz_net_devices) { uint8 frname[30]; @@ -564,7 +583,17 @@ void print_routing_info(int force) : ( (nd->is_up==1) ? "UP" : "ADDED") ); } - fprintf(f, "<--------- Routing Table ---------->\n"); + if (print_route_mode&2) { + f= open_route_info_fn(1, f, 2); + fprintf(f, "%s", ctime(&xtime) ); + } + i=0; + k=-1; + while (++k < anz_routes) { + NW_ROUTES *nr = nw_routes[k]; + if (nr->net) i++; + } + fprintf(f, "<--------- %d Routes ---------->\n", i); fprintf(f, "%8s Hops Ticks %9s Router Node\n", "Network", "RouterNet"); k=-1; while (++k < anz_routes) { @@ -576,15 +605,25 @@ void print_routing_info(int force) (int)nr->rnode[3], (int)nr->rnode[4], (int)nr->rnode[5]); } } + if (print_route_mode&2) { + f= open_route_info_fn(1, f, 3); + fprintf(f, "%s", ctime(&xtime) ); + } + i=0; k=-1; - fprintf(f, "<--------- Server Table ---------->\n"); + while (++k < anz_servers) { + NW_SERVERS *ns = nw_servers[k]; + if (ns->typ) i++; + } + fprintf(f, "<--------- %d Servers ---------->\n", i); fprintf(f, "%-20s %4s %9s Hops Server-Address\n","Name", "Typ", "RouterNet"); + k=-1; while (++k < anz_servers) { NW_SERVERS *ns = nw_servers[k]; if (ns->typ) { char sname[50]; strmaxcpy(sname, ns->name, 20); - fprintf(f, "%-20s %4d %08lX %4d %s\n", sname, ns->typ, + fprintf(f, "%-20s %4x %08lX %4d %s\n", sname, ns->typ, ns->net, ns->hops, xvisable_ipx_adr(&(ns->addr), 1)); } } /* while */ @@ -716,8 +755,7 @@ int test_ins_device_net(uint32 rnet) if ( foundfree < 0 ) { if (anz_net_devices < MAX_NET_DEVICES) { NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]); - nd=*pnd= (NW_NET_DEVICE*)xmalloc(sizeof(NW_NET_DEVICE)); - memset(nd, 0, sizeof(NW_NET_DEVICE)); + nd=*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE)); nd->ticks = 1; } else { XDPRINTF((1, 0, "too many devices > %d, increase MAX_NET_DEVICES in config.h", anz_net_devices)); diff --git a/nwserv.c b/nwserv.c index a549cf8..94aa1c8 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,4 +1,4 @@ -/* nwserv.c 03-May-96 */ +/* nwserv.c 09-Nov-96 */ /* MAIN Prog for NWSERV + NWROUTED */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -120,6 +120,12 @@ static char *prog_name_typ="SERVER"; #define IN_PROG NWSERV #endif +#if !IN_NWROUTED +static int ipx_out_fd=-1; +/* next should be '1', is for testing only */ +#define USE_PERMANENT_OUT_SOCKET 1 + + static void add_wdata(IPX_DATA *d, char *data, int size) { memcpy(d->owndata.d.data+d->owndata.d.size, data, size); @@ -128,18 +134,25 @@ static void add_wdata(IPX_DATA *d, char *data, int size) static void write_wdata(IPX_DATA *d, int what, int sock) { - ipxAddr_t toaddr; - d->owndata.d.function=what; - d->owndata.d.size +=sizeof(int); - memset(d->owndata.type, 0xee, 2); - d->owndata.sequence = 0; - d->owndata.connection = 0; - memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t)); - U16_TO_BE16(sock, toaddr.sock); - send_ipx_data(-1, 17, - OWN_DATA_IPX_BASE_SIZE + sizeof(int)+d->owndata.d.size, (char*)d, - &toaddr, (sock == SOCK_NCP) ? "NCPSERV" : "NWBIND" ); - d->owndata.d.size=0; + int fd = (ipx_out_fd > -1) ? ipx_out_fd : open_ipx_socket(NULL, 0); + if (fd > -1) { + ipxAddr_t toaddr; + d->owndata.d.function=what; + d->owndata.d.size +=sizeof(int); + memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t)); + U16_TO_BE16(sock, toaddr.sock); + if (send_own_data(fd, d, &toaddr)) { + errorp(0, "write_wdata", "to %s", + (sock == SOCK_NCP) ? "NCPSERV" : "NWBIND" ); + } + d->owndata.d.size=0; + if (ipx_out_fd != fd) { + t_unbind(fd); + t_close(fd); + } + } else { + errorp(0, "write_wdata", "fd not open"); + } } static void write_to_sons(int what, int connection, @@ -178,12 +191,8 @@ static void write_to_sons(int what, int connection, write_wdata(&ipxd, what, sock); } -#if !IN_NWROUTED -# define write_to_ncpserv(what, connection, data, data_size) \ +#define write_to_ncpserv(what, connection, data, data_size) \ write_to_sons((what), (connection), (data), (data_size), SOCK_NCP) -#else -# define write_to_ncpserv(what, connection, data, data_size) /* */ -#endif #define write_to_nwbind(what, connection, data, data_size) \ write_to_sons((what), (connection), (data), (data_size), sock_nwbind) @@ -215,39 +224,31 @@ void ins_del_bind_net_addr(uint8 *name, int styp, ipxAddr_t *adr) write_to_nwbind(0x3333, 0, (char *)buf, len); } -static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode) +static int loc_open_ipx_socket(int sock_nr, int nr) { - int ipx_fd=t_open("/dev/ipx", open_mode, NULL); - struct t_bind bind; - if (ipx_fd < 0) { - t_error("t_open !Ok"); - return(-1); - } - memset(&my_server_adr, 0, sizeof(ipxAddr_t)); - U16_TO_BE16(sock_nr, my_server_adr.sock); /* actual read socket */ - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)&my_server_adr; - bind.qlen = 0; /* ever */ - - if (t_bind(ipx_fd, &bind, &bind) < 0){ - char sxx[200]; - sprintf(sxx,"NWSERV:t_bind !OK in open_ipx_socket, sock=0x%x", (int) sock_nr); - t_error(sxx); - t_close(ipx_fd); - return(-1); - } - sock_nummern[nr] = GET_BE16(my_server_adr.sock); /* really socket nmbr */ - if (nw_debug) print_ipx_addr(&my_server_adr); + int ipx_fd=open_ipx_socket(&my_server_adr, sock_nr); + if (ipx_fd > -1) { + sock_nummern[nr] = GET_BE16(my_server_adr.sock); /* really socket nmbr */ + if (nw_debug) + print_ipx_addr(&my_server_adr); + } else + errorp(0, "loc_open_ipx_socket", "nr=%d", sock_nr); return(ipx_fd); } +#else +# define USE_PERMANENT_OUT_SOCKET 0 +# define write_to_ncpserv(what, connection, data, data_size) /* */ +# define write_to_nwbind(what, connection, data, data_size) /* */ +#endif + static int start_ncpserv(char *nwname, ipxAddr_t *addr) { #if !IN_NWROUTED int fds_in[2]; int pid; - if (pipe(fds_in) < 0) return(-1); + if (pipe(fds_in) < 0) + return(-1); switch (pid=fork()) { case 0 : { /* new Process */ @@ -279,30 +280,20 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr) close(fds_in[1]); fd_ncpserv_in = fds_in[0]; pid_ncpserv = pid; + sleep(2); #endif - U16_TO_BE16(SOCK_NCP, addr->sock); return(0); /* OK */ } -static int start_nwbind(char *nwname, ipxAddr_t *addr) +static int start_nwbind(char *nwname) { #if !IN_NWROUTED - int fds_in[2]; - int pid; - struct t_bind bind; - int ipx_fd=t_open("/dev/ipx", O_RDWR, NULL); + int fds_in[2]; + int pid; + ipxAddr_t addr; + int ipx_fd=open_ipx_socket(&addr, 0); if (ipx_fd < 0) { - errorp(1, "start_nwbind", "t_open"); - return(-1); - } - U16_TO_BE16(SOCK_AUTO, addr->sock); - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)addr; - bind.qlen = 0; /* allways */ - if (t_bind(ipx_fd, &bind, &bind) < 0){ - errorp(1, "start_nwbind", "t_bind"); - t_close(ipx_fd); + errorp(1, "start_nwbind", NULL); return(-1); } if (pipe(fds_in) < 0){ @@ -310,8 +301,7 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr) t_close(ipx_fd); return(-1); } - sock_nwbind = (int) GET_BE16(addr->sock); - + sock_nwbind = (int) GET_BE16(addr.sock); switch (pid=fork()) { case 0 : { /* new Process */ char *progname="nwbind"; @@ -329,8 +319,8 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr) close(ipx_fd); while (j++ < 100) close(j); /* close all > FD_NWSERV */ - U16_TO_BE16(SOCK_NCP, addr->sock); - ipx_addr_to_adr(addrstr, addr); + U16_TO_BE16(SOCK_NCP, addr.sock); + ipx_addr_to_adr(addrstr, &addr); sprintf(nwbindsock, "%04x", sock_nwbind); execl(get_exec_path(pathname, progname), progname, nwname, addrstr, nwbindsock, NULL); @@ -348,6 +338,7 @@ static int start_nwbind(char *nwname, ipxAddr_t *addr) close(ipx_fd); fd_nwbind_in = fds_in[0]; pid_nwbind = pid; + sleep(2); #endif return(0); /* OK */ } @@ -535,7 +526,7 @@ static void handle_sap(int fd, int server_type = GET_BE16(ipxdata->sqp.server_type); if (query_type == 3) { - XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d von %s", + XDPRINTF((2,0,"SAP NEAREST SERVER request typ=%d from %s", server_type, visable_ipx_adr(from_addr))); /* Get Nearest File Server */ if (!nearest_request_flag) @@ -570,8 +561,9 @@ 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 if (type == 4) { /* from Fileserver */ +#endif if (16 == hops) { /* shutdown */ XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name)); @@ -580,7 +572,9 @@ static void handle_sap(int fd, get_server_data((char*)name, ad, from_addr); insert_delete_server(name, type, ad, from_addr, hops, 0, 0); } +#if !HANDLE_ALL_SAP_TYPS } +#endif p+=sizeof(SAPS); } /* while */ } else { @@ -836,8 +830,7 @@ static void get_ini(int full) break; #if INTERNAL_RIP_SAP - case 3 : - if (full) { + case 3 : if (full) { upstr(inhalt); if (!strcmp(inhalt, "AUTO")) internal_net = 0; else { @@ -856,12 +849,14 @@ static void get_ini(int full) if (NULL != hent && hent->h_length == 4) { internal_net = GET_BE32(*(hent->h_addr_list)); } else { - XDPRINTF((0, 0, "Cannot gethostbyname from '%s'", - locname)); + errorp(10, "Get_ini", "Cannot gethostbyname from '%s'", + locname); if (hent) { XDPRINTF((0, 0, "hent->h_length=%d", hent->h_length)); } } + if (0==internal_net) + errorp(11, "Get_ini", "Cannot get AUTO internal net with help of gethostbyname"); } } break; @@ -881,7 +876,7 @@ static void get_ini(int full) if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1) sscanf(inhalt, "%lx", &nd->net); - if (nd->net == internal_net) { + if (nd->net && (nd->net == internal_net)) { errorp(11, "Get_ini", "device net 0x%lx = internal net", nd->net); exit(1); } @@ -939,7 +934,7 @@ static void get_ini(int full) case 301 : new_str(pr_route_info_fn, (uint8*)inhalt); break; - case 302 : print_route_mode=atoi(inhalt); + case 302 : print_route_mode=hextoi(inhalt); break; case 310 : wdogs_till_tics=atoi(inhalt); @@ -1028,7 +1023,12 @@ static void send_down_broadcast(void) static void close_all(void) { int j = NEEDED_SOCKETS; - +#if USE_PERMANENT_OUT_SOCKET + if (ipx_out_fd > -1) { + t_unbind(ipx_out_fd); + t_close(ipx_out_fd); + } +#endif while (j--) { t_unbind(sockfd[j]); t_close(sockfd[j]); @@ -1189,7 +1189,7 @@ int main(int argc, char **argv) polls[j].events = POLLIN|POLLPRI; polls[j].revents = 0; if (j < NEEDED_SOCKETS) { - int fd = open_ipx_socket(ipx_sock_nummern[j], j, O_RDWR); + int fd = loc_open_ipx_socket(ipx_sock_nummern[j], j); if (fd < 0) { while (j--) { t_unbind(sockfd[j]); @@ -1205,11 +1205,20 @@ int main(int argc, char **argv) } } +#if USE_PERMANENT_OUT_SOCKET + ipx_out_fd=open_ipx_socket(NULL, 0); +#endif + #if !IN_NWROUTED + XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s", + (ipx_out_fd > -1) ? "enabled" : "disabled")); + + XDPRINTF((1, 0, "IPX_MAX_DATA=%d, RW_BUFFERSIZE =%d", + IPX_MAX_DATA, RW_BUFFERSIZE)); signal(SIGCHLD, sig_chld); #endif - if ( !start_nwbind( my_nwname, &my_server_adr) + if ( !start_nwbind(my_nwname) && !start_ncpserv(my_nwname, &my_server_adr) ) { /* now do polling */ time_t broadtime; @@ -1217,18 +1226,17 @@ int main(int argc, char **argv) set_sigs(); polls[NEEDED_SOCKETS].fd = fd_nwbind_in; + U16_TO_BE16(SOCK_NCP, my_server_adr.sock); #if !IN_NWROUTED { ipxAddr_t server_adr_sap; polls[NEEDED_SOCKETS+1].fd = fd_ncpserv_in; - U16_TO_BE16(SOCK_NCP, my_server_adr.sock); memcpy(&server_adr_sap, &my_server_adr, sizeof(ipxAddr_t)); U16_TO_BE16(SOCK_SAP, server_adr_sap.sock); insert_delete_server((uint8*)my_nwname, 0x4, &my_server_adr, &server_adr_sap, 0, 0, 0); } #endif - while (!server_is_down) { int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs); int call_wdog=0; diff --git a/nwvolume.c b/nwvolume.c index 20ae083..3896dd2 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 08-Aug-96 */ +/* nwvolume.c 07-Nov-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -33,6 +33,18 @@ NW_VOL nw_volumes[MAX_NW_VOLS]; int used_nw_volumes=0; +static void volume_to_namespace_map(int volume, NW_VOL *vol) +{ + struct stat statb; + DEV_NAMESPACE_MAP dnm; + if (stat(vol->unixname, &statb)) { + XDPRINTF((1, 0, "cannot stat vol=%d, `%s`", volume, vol->unixname)); + } + dnm.dev = statb.st_dev; + dnm.namespace = 0; /* NAMESPACE DOS */ + (void) nw_vol_inode_to_handle(volume, statb.st_ino, &dnm); +} + void nw_init_volumes(FILE *f) /* f = inifile Pointer, must be opened !! */ { @@ -123,7 +135,8 @@ void nw_init_volumes(FILE *f) vol->max_maps_count = MAX_DEV_NAMESPACE_MAPS; vol->high_inode = 0xfffffff; } - + if (vol->unixnamlen) + volume_to_namespace_map(used_nw_volumes-1, vol); } } } /* while */ @@ -141,10 +154,15 @@ void nw_setup_home_vol(int len, uint8 *fn) unixname[len] = '\0'; } } - while (k--) { + while (k--) { /* now set all HOME volumes */ if (nw_volumes[k].options & VOL_OPTION_IS_HOME) { + int i = -1; + while (++i < nw_volumes[k].maps_count) + xfree(nw_volumes[k].dev_namespace_maps[i]); + nw_volumes[k].maps_count = 0; nw_volumes[k].unixnamlen = len; new_str(nw_volumes[k].unixname, unixname); + volume_to_namespace_map(k, &(nw_volumes[k])); } } }