From 2faf2711b46a50cd60eaf50c59ce728dc556b464 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.pl03 --- connect.c | 145 +++++++++++---------- connect.h | 2 + dbmtool.c | 49 +++++++ doc/CHANGES | 21 ++- doc/CREDITS | 3 + doc/FRAGEN.erik | 3 + doc/NEWS | 8 ++ doc/mars_nwe.lsm | 6 +- emutli.c | 6 +- examples/comm.c | 61 +++++++++ examples/comm.exe | Bin 0 -> 35048 bytes examples/unxcomm.c | 68 ++++++++++ makefile.unx | 16 ++- namspace.c | 223 +++++++++++++------------------ nwbind.c | 11 +- nwclient.c | 15 ++- nwconn.c | 51 ++++---- nwdbm.c | 319 +++++++++++++++++++++++++++++++++++++++++---- nwdbm.h | 1 - nwfile.c | 113 +++++++++++----- nwqueue.h | 1 + nwserv.c | 3 + nwvolume.c | 8 ++ 23 files changed, 838 insertions(+), 295 deletions(-) create mode 100644 dbmtool.c create mode 100644 examples/comm.c create mode 100755 examples/comm.exe create mode 100644 examples/unxcomm.c diff --git a/connect.c b/connect.c index 649502f..92c0a45 100644 --- a/connect.c +++ b/connect.c @@ -398,9 +398,6 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, || ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); -#if 0 - if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); -#endif XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode)); result = (*fs_func)(nwpath, fs); if (result < 0) break; @@ -471,9 +468,6 @@ static int get_dir_entry(NW_PATH *nwpath, || ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)nwpath->fn, (char*)name); -#if 0 - if (soptions & VOL_OPTION_DOWNSHIFT) upstr(nwpath->fn); -#endif XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode)); break; /* ready */ } @@ -564,9 +558,6 @@ static int get_dh_entry(DIR_HANDLE *dh, || (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ strcpy((char*)search, (char*)name); -#if 0 - if (dh->vol_options & VOL_OPTION_DOWNSHIFT) upstr(search); -#endif break; /* ready */ } } else okflag = 0; @@ -703,21 +694,26 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ { uint8 searchpath[256]; uint8 *p=searchpath; + uint8 *ppp=nwpath->path; int completition=0; - strcpy((char*)searchpath, (char*)nwpath->path); /* save path */ + strcpy((char*)searchpath, (char*)ppp); /* save path */ if (nwpath->volume > -1) { /* absolute path */ - nwpath->path[0] = '\0'; + *ppp= '\0'; } else { /* volume not kwown yet, I must get it about dir_handle */ if (dir_handle > 0 && --dir_handle < (int)used_dirs && dirs[dir_handle].inode){ nwpath->volume = dirs[dir_handle].volume; if (searchpath[0] == '/') { /* absolute path */ p++; - nwpath->path[0] = '\0'; - } else /* get path from dir_handle */ - strcpy((char*)nwpath->path, (char*)dirs[dir_handle].path); + *ppp = '\0'; + } else { /* get path from dir_handle */ + NW_VOL *v = &nw_volumes[nwpath->volume]; + strcpy((char*)ppp, (char*)dirs[dir_handle].path); + if (v->options & VOL_OPTION_IGNCASE) + ppp += strlen(ppp); + } } else return(-0x9b); /* wrong dir handle */ } if (*p) { @@ -777,28 +773,32 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ } } } + if (!completition) { if (nwpath->volume > -1 && nwpath->volume < used_nw_volumes){ NW_VOL *v = &nw_volumes[nwpath->volume]; if (v->options & VOL_OPTION_DOWNSHIFT) { - downstr(nwpath->path); + downstr(ppp); downstr(nwpath->fn); } else { - upstr(nwpath->path); + upstr(ppp); upstr(nwpath->fn); } if (v->options & VOL_OPTION_IGNCASE) { uint8 unixname[1024]; /* should be enough */ uint8 *pp=unixname+v->unixnamlen; + int offset = ppp - nwpath->path; int pathlen = strlen(nwpath->path); int fnlen = strlen(nwpath->fn); memcpy(unixname, v->unixname, v->unixnamlen); strcpy(pp, nwpath->path); if (fnlen) strcpy(pp+pathlen, nwpath->fn); + pp += offset; + pathlen -= offset; mangle_dos_name(v, unixname, pp); XDPRINTF((5, 0, "Mangled DOS/unixname=%s", unixname)); - memcpy(nwpath->path, pp, pathlen); + memcpy(ppp, pp, pathlen); if (fnlen) memcpy(nwpath->fn, pp+pathlen, fnlen); } @@ -886,33 +886,33 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode) if (!mode) { /* UNIX access -> NW access */ attrib = 0x20; - if (act_uid == stb->st_uid) { - if (!(stb->st_mode & S_IWUSR)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IRUSR)) { - attrib |= 0x2; /* Hidden */ - } - } else if (act_gid == stb->st_gid) { - if (!(stb->st_mode & S_IWGRP)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IRGRP)) { - attrib |= 0x2; /* Hidden */ - } - } else { - if (!(stb->st_mode & S_IWOTH)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IROTH)) { - attrib |= 0x2; /* Hidden */ + if (act_uid) { + if (act_uid == stb->st_uid) { + if (!(stb->st_mode & S_IWUSR)) { + attrib |= 0x1; /* RO */ + } + if (!(stb->st_mode & S_IRUSR)) { + attrib |= 0x2; /* Hidden */ + } + } else if (act_gid == stb->st_gid) { + if (!(stb->st_mode & S_IWGRP)) { + attrib |= 0x1; /* RO */ + } + if (!(stb->st_mode & S_IRGRP)) { + attrib |= 0x2; /* Hidden */ + } + } else { + if (!(stb->st_mode & S_IWOTH)) { + attrib |= 0x1; /* RO */ + } + if (!(stb->st_mode & S_IROTH)) { + attrib |= 0x2; /* Hidden */ + } } } /* only shared if gid == gid && x Flag */ - if ((act_gid == stb->st_gid) && (stb->st_mode & S_IXGRP)) attrib |= 0x80; /* shared flag */ - return(attrib); } else { /* NW access -> UNIX access */ @@ -940,10 +940,14 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode) static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { + int voloptions=get_volume_options(nwpath->volume, 1); strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); f->attrib=0; /* d->name could be too long */ upstr(f->name); - f->attrib = (uint8) un_nw_attrib(stb, 0, 0); + if (voloptions & VOL_OPTION_IS_PIPE) + f->attrib = 0; + else + f->attrib = (uint8) un_nw_attrib(stb, 0, 0); XDPRINTF((5,0, "get_file_attrib = 0x%x of ,%s, uid=%d, gid=%d", (int)f->attrib, conn_get_nwpath_name(nwpath), stb->st_uid, stb->st_gid)); @@ -1121,7 +1125,7 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, int optq = get_volume_options(quellpath.volume, 1); int optz = get_volume_options(zielpath.volume, 1); if ((optq & VOL_OPTION_IS_PIPE) || - (optz & VOL_OPTION_IS_PIPE)) completition = -0x9c; + (optz & VOL_OPTION_IS_PIPE)) completition = -0x8b; else if ((optq & VOL_OPTION_READONLY) || (optz & VOL_OPTION_READONLY)) completition = -0x8b; } @@ -1130,18 +1134,13 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, char unziel[256]; strcpy(unquelle, build_unix_name(&quellpath,0)); strcpy(unziel, build_unix_name(&zielpath,0)); - if (!link(unquelle, unziel)){ - if (unlink(unquelle)) { - completition=-0x8b; - /* TODO: here completition must be no pernmissions */ - unlink(unziel); - } - } else { - if (errno == EEXIST) - completition=-0x92; /* allready exist */ - else if (errno == EXDEV) - completition=-0x9a; /* cross devices */ - else completition=-0x9c; /* wrong path */ + completition = unx_mvfile(unquelle, unziel); + switch (completition) { + case 0 : break; + case EEXIST : completition = -0x92; break; /* allready exist */ + case EXDEV : completition = -0x9a; break; /* cross device */ + case EROFS : completition = -0x8b; break; /* no rights */ + default : completition = -0xff; } } } @@ -1161,7 +1160,7 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, int optq = get_volume_options(quellpath.volume, 1); int optz = get_volume_options(zielpath.volume, 1); if ((optq & VOL_OPTION_IS_PIPE) || - (optz & VOL_OPTION_IS_PIPE)) completition = -0x9c; + (optz & VOL_OPTION_IS_PIPE)) completition = -0x8b; else if ((optq & VOL_OPTION_READONLY) || (optz & VOL_OPTION_READONLY)) completition = -0x8b; } @@ -1195,7 +1194,9 @@ static int change_dir_entry( NW_DIR *dir, int volume, int new_entry, int task) { if (new_entry || (dir->inode && dir->is_temp != 2)) { - int len=strlen(path); + int len; + if (*path=='/' && *(path+1) != '\0') path++; + len=strlen(path); if (dir->path) xfree(dir->path); dir->path=xmalloc(len+2); if (len) { @@ -1212,14 +1213,12 @@ static int change_dir_entry( NW_DIR *dir, int volume, dir->inode = inode; dir->volume = (uint8) volume; dir->timestamp = time(NULL); - if (driveletter > -1) { dir->drive = (uint8) driveletter; dir->task = (uint8)task; } else { if (task < (int)dir->task) dir->task = (uint8) task; } - if (is_temp > -1) dir->is_temp = (uint8) is_temp; return(0); } else { @@ -1285,7 +1284,8 @@ int nw_init_connect(void) errorp(1, "No Volumes defined. Look at ini file entry 1, Abort !!", NULL); return(-1); } - + if (get_volume_options(0, 1) & VOL_OPTION_DOWNSHIFT) + downstr(nwlogin.path); if (stat(build_unix_name(&nwlogin, 0), &stbuff)) { errorp(1, "Stat error LOGIN Directory, Abort !!", "UnixPath=`%s`", build_unix_name(&nwlogin, 0)); @@ -1531,6 +1531,7 @@ int nw_get_directory_path(int dir_handle, uint8 *name) if (volume > -1 && volume < used_nw_volumes){ result=sprintf((char*)name, "%s:%s", nw_volumes[volume].sysname, dirs[dir_handle].path); if (name[result-1] == '/') name[--result] = '\0'; + upstr(name); } else result = -0x98; } XDPRINTF((5,0,"nw_get_directory_path:%s: Handle=%d, result=0x%x", name, dir_handle+1, result)); @@ -1684,9 +1685,11 @@ int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr, void get_dos_file_attrib(NW_DOS_FILE_INFO *f, struct stat *stb, + int volume, uint8 *path) { uint8 spath[14]; + int voloptions=get_volume_options(volume, 1); f->namlen=min(strlen((char*)path), 12); strmaxcpy(spath, path, 12); upstr(spath); @@ -1694,7 +1697,10 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, /* Attribute */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ - f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); + if (voloptions & VOL_OPTION_IS_PIPE) + f->attributes[0] = 0; + else + 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(1, f->created.id); @@ -1705,6 +1711,7 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, struct stat *stb, + int volume, uint8 *path) { uint8 spath[14]; @@ -1751,10 +1758,10 @@ int nw_scan_a_directory(uint8 *rdata, if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) { get_dos_dir_attrib(&(scif->u.d), &stbuff, - nwpath.fn); + nwpath.volume, nwpath.fn); } else { get_dos_file_attrib(&(scif->u.f), &stbuff, - nwpath.fn); + nwpath.volume, nwpath.fn); } return(sizeof(NW_SCAN_DIR_INFO)); } else return(-0xff); /* not found */ @@ -1774,7 +1781,7 @@ int nw_scan_a_root_dir(uint8 *rdata, if (!stat(build_unix_name(&nwpath, 2), &stbuff)) { NW_DOS_DIR_INFO *d=(NW_DOS_DIR_INFO*)rdata; memset(rdata, 0, sizeof(NW_DOS_DIR_INFO)); - get_dos_dir_attrib(d, &stbuff, nwpath.fn); + get_dos_dir_attrib(d, &stbuff, nwpath.volume, nwpath.fn); return(sizeof(NW_DOS_DIR_INFO)); } else return(-0xff); /* not found */ } else return(completition); /* wrong path */ @@ -1804,21 +1811,24 @@ static int my_match(uint8 *s, uint8 *p) static int get_match(uint8 *unixname, uint8 *p) { DIR *d; + uint8 *pp; if (!p || !*p) return(1); *p = '\0'; + pp=p+1; + while (*pp == '/') ++pp; if (NULL != (d=opendir(unixname))) { struct dirent *dirbuff; - XDPRINTF((10, 0, "opendir OK unixname='%s' p='%s'", unixname, p+1)); + XDPRINTF((10, 0, "opendir OK unixname='%s' pp='%s'", unixname, pp)); *p = '/'; while ((dirbuff = readdir(d)) != (struct dirent*)NULL){ 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, p+1))) { - memcpy(p+1, dirbuff->d_name, len); + if (0 != (len=my_match(dirbuff->d_name, pp))) { + memcpy(pp, dirbuff->d_name, len); XDPRINTF((10, 0, "get match, match OK")); closedir(d); - return(get_match(unixname, p+1+len)); + return(get_match(unixname, pp+len)); } } } @@ -1832,6 +1842,9 @@ static int get_match(uint8 *unixname, uint8 *p) void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp) { + struct stat stb; + if (!stat(unixname, &stb)) /* path is ok I hope */ + return; get_match(unixname, pp-1); } diff --git a/connect.h b/connect.h index 6a6be8b..db3ed93 100644 --- a/connect.h +++ b/connect.h @@ -183,10 +183,12 @@ extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len, extern void get_dos_file_attrib(NW_DOS_FILE_INFO *f, struct stat *stb, + int volume, uint8 *path); void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, struct stat *stb, + int volume, uint8 *path); diff --git a/dbmtool.c b/dbmtool.c new file mode 100644 index 0000000..8c851f2 --- /dev/null +++ b/dbmtool.c @@ -0,0 +1,49 @@ +/* dbmtool.c 08-Sep-96 data base tool program for mars_nwe */ +/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "net.h" +#include "nwdbm.h" + +/* dummy to make nwdbm happy */ +int b_acc(uint32 obj_id, int security, int forwrite) +{ + return(0); +} + +static int usage(char *s) +{ + char *p=strrchr(s, '/'); + fprintf(stderr, "usage:\t%s e | i | r [path]\n", p ? p+1 : s); + fprintf(stderr, "\te = export\n"); + fprintf(stderr, "\ti = import\n"); + fprintf(stderr, "\tr = repair\n"); + return(1); +} + +int main(int argc, char *argv[]) +{ + init_tools(0, 0); + if (argc < 2) return(usage(argv[0])); + if (*argv[1] == 'e') return(do_export_dbm(argv[2])); + else if (*argv[1] == 'i') return(do_import_dbm(argv[2])); + else if (*argv[1] == 'r') if (!do_export_dbm(argv[2])) + return(do_import_dbm(argv[2])); + else return(1); + else usage(argv[0]); + return(0); +} diff --git a/doc/CHANGES b/doc/CHANGES index 146eb2a..31b159d 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 : 22-Jul-96 +Aenderungen in mars_nwe bis zum : 09-Sep-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -166,5 +166,22 @@ Erste 'oeffentliche' Version - bessere OS2 Nameunterstuetzung. - 0x17 0x81 als Dummy implementiert fuer Windows Client. <----- ^^^^^^^^^^ pl1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +- mvdir call korrigiert. +- PIPE Filesystem erweitert. Nun wird Prog erst beim + ersten read oder write aufgerufen. Arbeitet nun + auch mit 'gleichzeitigen' lesen und schreiben. +- In Routinen 0x16,2c u. 0x16,2d sec per block auf 8 gesetzt. +- Access von Bindery Object 1 (Supervisor) auf 0x31 abgeaendert. +- Loeschung eines nicht vorhandenen property members erzeugt + keinen Fehlerkode mehr. +<----- ^^^^^^^^^^ pl2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- LOGIN Verzeichnis auf '-k' volume kann nun wieder in + downshift sein. Fehler war durch Implementation von Schalter 'i' + hineingerutscht. +- SHADOW_PWD Zusatz beim automatischen Umwandeln der + Unix User > mars_nwe User eingebaut. + Hinweis von: Herbert Rosmanith +- einfache dbm export/import Routinen eingebaut. +- Bug in dos_mangling routine beseitigt. +<----- ^^^^^^^^^^ pl3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index e077f40..9dae0b2 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -34,6 +34,9 @@ Jiri A. Randus Gregory Steuck testings and errorreports +Erik Thiele + testings and doc + Winfried Truemper : re-wrote `INSTALL' and added explanations to `nw.ini' diff --git a/doc/FRAGEN.erik b/doc/FRAGEN.erik index e02e6c0..c93d84e 100644 --- a/doc/FRAGEN.erik +++ b/doc/FRAGEN.erik @@ -1,5 +1,8 @@ Sorry, this is in German only. folgende Fragen/Antworten stammen von Erik Thiele. +EMAIL: erik@escape.mos.unterland.de +later: erik@escape.unterland.de \\\\ + > Heisst das, dass mars_nwe die Novell-Partition lesen kann? ________ diff --git a/doc/NEWS b/doc/NEWS index 957bb54..5dd7c3c 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,12 @@ # in this files are some notes for user of mars_nwe. +------24-Aug-96--- 0.98.pl2 ---------- +- 'PIPE' filesystem scheme changed. Now the first read or write + calls the 'pipe program' and not the open or creat call. + Therefore the first parameter is READ or WRITE and never CREAT! + Also a pipe command may have two 'channels' (read and write). + There is a little programpair comm.c/unxcomm.c in the + examples directory which explains the new scheme, + by reading the code ;). ------30-Jul-96--- 0.98.pl1 ---------- - better OS2 name handling (upper/lowercase) ------22-Jul-96--- 0.98.pl0 ---------- diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 5d37c5d..065a46c 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98.pl1 -Entered-date: 14-Aug-96 +Version: 0.98.pl3 +Entered-date: 10-Sep-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 - 165kB mars_nwe-0.98.pl1.tgz + 200kB mars_nwe-0.98.pl3.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 eea0f1f..4104870 100644 --- a/emutli.c +++ b/emutli.c @@ -217,7 +217,7 @@ static void sig_alarm(int rsig) signal(rsig, SIG_IGN); XDPRINTF((0, 0,"GOT ALARM try=%d, sendto=%s", anz_tries+1, visable_ipx_adr((ipxAddr_t *) test_ud->addr.buf) )); - if (anz_tries++ < 3) new_try++; + if (anz_tries++ < 10) new_try++; } #endif @@ -230,12 +230,12 @@ int t_sndudata(int fd, struct t_unitdata *ud) #if DO_IPX_SEND_TEST { - anz_tries=0; + anz_tries=1; test_ud =ud; do { void (*old_sig)(int rsig) = signal(SIGALRM, sig_alarm); new_try = 0; - alarm(2); + alarm(1+anz_tries); #endif memset(&ipxs, 0, sizeof(struct sockaddr_ipx)); ipxs.sipx_family=AF_IPX; diff --git a/examples/comm.c b/examples/comm.c new file mode 100644 index 0000000..7504e64 --- /dev/null +++ b/examples/comm.c @@ -0,0 +1,61 @@ +/* + * simple demo for a command programm which do a + * DOS <-> UNX command handling using PIPE filesystem. + * can be used with unxcomm for UNX. + * + * Can also be used under Linux for ncpfs <-> mars_nwe. + * + */ + +#define ENV_UNXCOMM "UNXCOMM" +#ifdef LINUX +# define DEFAULT_COMM "/pipes/unxcomm" +# else +# define DEFAULT_COMM "p:/unxcomm" +#endif + +#include +#include +#include +#ifndef LINUX +# include +#endif +#include + +static int usage(char *progname) +{ + fprintf(stderr, "Usage:\t%s prog [paras]\n", progname); + return(1); +} + +int main(int argc, char **argv) +{ + char *unxcomm=getenv("UNXCOMM"); + if (NULL == unxcomm) unxcomm=DEFAULT_COMM; + if (argc > 1) { + int fdout = open(unxcomm, O_RDWR); + int fdin = dup(fdout); + if (fdout > -1 && fdin > -1) { + char **pp=argv+1; + unsigned char b=32; + int size; + int buf[512]; + while(--argc) { + write(fdout, *pp, strlen(*pp)); + ++pp; + write(fdout, &b, 1); + } + b=0; + write(fdout, &b, 1); + close(fdout); + + 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(usage(argv[0])); +} diff --git a/examples/comm.exe b/examples/comm.exe new file mode 100755 index 0000000000000000000000000000000000000000..0d074a54caa0e583d402f2c0bc04b5548550c584 GIT binary patch literal 35048 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 literal 0 HcmV?d00001 diff --git a/examples/unxcomm.c b/examples/unxcomm.c new file mode 100644 index 0000000..628fcca --- /dev/null +++ b/examples/unxcomm.c @@ -0,0 +1,68 @@ +/* simple UNX program to work together with 'comm' */ +#include +#include + +static char **build_argv(int bufsize, char *command, int len) +/* routine returns **argv for use with execv routines */ +{ + int offset = ((len+4) / 4) * 4; /* aligned offset for **argv */ + int components = (bufsize - offset) / 4; + if (components-- > 1) { /* minimal argv[0] + NULL */ + char **argv = (char **)(command+offset); + char **pp = argv; + char *p = command; + char c; + int i=0; + *pp = p; + *(p+len) = 0; + while ((0 != (c = *p++)) && i < components) { + if (c == 10 || c == 13) { + *(p-1) = '\0'; + break; + } else if (c == 32 || c == '\t') { + *(p-1) = '\0'; + if (*p != 32 && *p != '\t' && *p != 10 && *p != 13) { + *(++pp)=p; + i++; + } + } else if (!i && c == '/') { /* here i must get argv[0] */ + *pp=p; + } + } + if (*pp && !**pp) *pp=NULL; + else + *(++pp)=NULL; + return(argv); + } + return(NULL); +} +#define MAXARGLEN 1024 + +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))){ + char **argvv=build_argv(sizeof(buf), buf, size); + if (argvv) { + char path[300]; + execv(buf, argvv); + sprintf(path, "/usr/bin/%s", *argvv); + execv(path, argvv); + sprintf(path, "/bin/%s", *argvv); + execv(path, argvv); + sprintf(path, "/usr/sbin/%s", *argvv); + execv(path, argvv); + sprintf(path, "/sbin/%s", *argvv); + execv(path, argvv); + fprintf(stderr, "%s:\tCould not find program '%s'\n", *argv, buf); + exit(1); + } + } + fprintf(stderr, "%s:\tGot no paras\n", *argv); + exit(1); +} diff --git a/makefile.unx b/makefile.unx index f294754..356866a 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 28-Jul-96 +#makefile.unx 30-Aug-96 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=98 -P_L=1 +P_L=3 #define D_P_L 1 DISTRIB=mars_nwe @@ -70,6 +70,7 @@ PROG4=ncpserv PROG5=nwclient PROG6=nwbind PROG7=nwrouted +PROG8=dbmtool #include "config.h" #ifdef FILENAME_NW_INI @@ -101,7 +102,8 @@ NWROUTED=$(PROG7) NWROUTE_O=nwroute1$(O) #endif -PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED) +INSTALLPROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED) +PROGS=$(INSTALLPROGS) $(PROG8) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) @@ -111,13 +113,14 @@ OBJ4= $(OBJ1) OBJ5= $(OBJ1) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) OBJ7= $(OBJ1) $(EMUTLIOBJ1) +OBJ8= $(OBJ6) OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ nwdbm$(O) nwcrypt$(O) unxlog$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ - $(PROG7)$(O) + $(PROG7)$(O) $(PROG8)$(O) HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ unxfile$(O) @@ -149,6 +152,9 @@ $(PROG6): $(PROG6)$(O) $(OBJ6) $(PROG7): $(PROG7)$(O) $(OBJ7) nwserv.c nwroute.c $(CC) -o $(VPATH)/$(PROG7) $(PROG7)$(O) $(OBJ7) $(NSLLIB) +$(PROG8): $(PROG8)$(O) $(OBJ8) + $(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) + $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h $(OBJS): net.h config.h @@ -166,7 +172,7 @@ n_install_ini: n_install: cd $(VPATH) && $(INSTALL) -d $(M_PATHNAME_PROGS) && cd $(OBJDIR) - cd $(VPATH) && $(INSTALL) $(PROGS) $(M_PATHNAME_PROGS) && cd $(OBJDIR) + cd $(VPATH) && $(INSTALL) $(INSTALLPROGS) $(M_PATHNAME_PROGS) && cd $(OBJDIR) @cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \ echo ""; \ echo "********************************************************"; \ diff --git a/namspace.c b/namspace.c index 7b360ae..6b5ef81 100644 --- a/namspace.c +++ b/namspace.c @@ -61,7 +61,6 @@ typedef struct { int slot; /* act slot in table */ int locked; /* if locked then do not remove */ /* and do not move till end */ - DIR_SEARCH_STRUCT *dir; /* for dir searches */ N_NW_PATH nwpath; } DIR_BASE_ENTRY; @@ -160,72 +159,34 @@ static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus, #define nwpath_2_unix2(nwpath, modus, extrabytes, extrastr) \ xnwpath_2_unix((nwpath), (modus), (extrabytes), extrastr) -static void free_dbe_dir(DIR_BASE_ENTRY *dbe) +static int downsort_dbe_entries(int dbase) { - DIR_SEARCH_STRUCT *d = dbe->dir; - if (NULL != d) { - if (d->fdir) closedir(d->fdir); - xfree(d->unixname); - xfree(dbe->dir); - } -} - -static int allocate_dbe_dir(DIR_BASE_ENTRY *dbe) -{ - DIR_SEARCH_STRUCT *d=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT)); - if (dbe->dir) free_dbe_dir(dbe); - dbe->dir = d; - d->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258); - XDPRINTF((4, 0, "UNIXNAME='%s'", d->unixname)); - d->fdir = opendir(d->unixname); - if (NULL == d->fdir) { - free_dbe_dir(dbe); - return(-0xff); - } else { - d->kpath = d->unixname+strlen(d->unixname); - *(d->kpath) = '/'; - *(++(d->kpath)) = '\0'; - return(0); - } -} - -static void free_dbe_ptr(DIR_BASE_ENTRY *dbe) -{ - if (dbe != (DIR_BASE_ENTRY*)NULL) { - free_dbe_dir(dbe); - xfree(dbe); - } -} - -static int base_open_seek_dir(DIR_BASE_ENTRY *dbe, uint32 offset) -/* opens a directory struct for searching */ -{ - int result = S_ISDIR(dbe->nwpath.statb.st_mode) ? 0 : -0xff; - if (!result) { - if (offset == MAX_U32) { - free_dbe_dir(dbe); - offset = 0L; + DIR_BASE_ENTRY **dbep=&(dir_base[dbase]); + DIR_BASE_ENTRY **dbpq=dbep; + int k=dbase; + while (k--) { + --dbpq; + if (!(*dbpq) || !(*dbpq)->locked) { + *dbep = *dbpq; + if (*dbep) (*dbep)->slot = dbase; + dbep=dbpq; + dbase=k; } - if (NULL == dbe->dir) result=allocate_dbe_dir(dbe); - if (result > -1) seekdir(dbe->dir->fdir, offset); } - if (result < 0 && NULL != dbe->dir) free_dbe_dir(dbe); - XDPRINTF((3, 0, "base_open_seek_dir offset=%d, result=%d", offset, result)); - return(result); + return(dbase); } - static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) -/* returns new allocated dir_base_entry */ +/* returns new allocated dir_base_entry_pointer */ { int j =-1; int to_use=-1; - DIR_BASE_ENTRY **pdbe=(DIR_BASE_ENTRY**) NULL; - - while (++j < anz_dbe && NULL != *(pdbe = &(dir_base[j])) ){ - if (!(*pdbe)->basehandle && j > 3 && !(*pdbe)->locked) to_use=j; - if ((*pdbe)->slot != j) { - XDPRINTF((0,0, "slot %d = %d", j, (*pdbe)->slot)); + DIR_BASE_ENTRY *dbe; + while (++j < anz_dbe && NULL != (dbe = dir_base[j])){ + if (j > 3 && !dbe->basehandle && !dbe->locked) + to_use=j; + if (dbe->slot != j) { + XDPRINTF((0,0, "slot %d != %d", j, dbe->slot)); } } @@ -233,65 +194,41 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) if (anz_dbe == MAX_DIR_BASE_ENTRIES) { if (to_use > -1) { j = to_use; - pdbe = &(dir_base[j]); } else { - while (j--) { - pdbe = &(dir_base[j]); - if (!(*pdbe)->locked) break; /* remove last not locked from list */ - } + while (j && dir_base[--j]->locked) ;; } - free_dbe_ptr(*pdbe); - } else pdbe = &(dir_base[anz_dbe++]); + xfree(dir_base[j]); + } else + anz_dbe++; + dir_base[j] = NULL; } - while (j--) { - *pdbe = dir_base[j]; - if (*pdbe) (*pdbe)->slot=j+1; - pdbe--; - } - *pdbe = (DIR_BASE_ENTRY*)xcmalloc(sizeof(DIR_BASE_ENTRY)); - (*pdbe)->slot = 0; - init_nwpath(&((*pdbe)->nwpath), namespace); - return(*pdbe); + j=downsort_dbe_entries(j); + dbe=dir_base[j]=(DIR_BASE_ENTRY*)xcmalloc(sizeof(DIR_BASE_ENTRY)); + dbe->slot = j; + init_nwpath(&(dbe->nwpath), namespace); + return(dbe); } static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe) { if (NULL != dbe && NULL != *dbe) { - int slot = (*dbe)->slot; - free_dbe_ptr(*dbe); - dir_base[slot] = *dbe = (DIR_BASE_ENTRY*)NULL; - if (slot+1 == anz_dbe) { - while (anz_dbe && ((DIR_BASE_ENTRY*)NULL == dir_base[anz_dbe-1]) ) + int slot=(*dbe)->slot; + xfree(*dbe); + *dbe=dir_base[slot] = NULL; + while (anz_dbe && ((DIR_BASE_ENTRY*)NULL == dir_base[anz_dbe-1]) ) --anz_dbe; - } } } #define free_dbe_p(dbe) xx_free_dbe_p(&(dbe)) -#define free_dbe(dbase) \ - xx_free_dbe_p(((dbase) > -1 && (dbase) < anz_dbe) ? &(dir_base[dbase]) : NULL) - static int touch_handle_entry_p(DIR_BASE_ENTRY *dbe) /* routine touchs this entry and returns the new offset */ { int dbase = (NULL != dbe) ? dbe->slot : -1; XDPRINTF((4, 0, "touch_handle_entry_p entry dbase=%d", dbase)); if (dbase > 4) { - DIR_BASE_ENTRY **dbp=&(dir_base[dbase]); - DIR_BASE_ENTRY **dbpq=dbp; - int aktbase=dbase; - - while (dbase--) { - --dbpq; - if (!(*dbpq) || !(*dbpq)->locked) { - *dbp = *dbpq; - if (*dbp) (*dbp)->slot = dbase+1; - dbp=dbpq; - aktbase=dbase; - } - } - - dbase = aktbase; + dir_base[dbase] = NULL; + dbase=downsort_dbe_entries(dbase); dir_base[dbase] = dbe; dbe->slot = dbase; } @@ -480,19 +417,18 @@ static int add_dbe_entry(int namspace, int volume, } if (stb) memcpy(&(dbe->nwpath.statb), stb, sizeof(struct stat)); - - return(touch_handle_entry_p(dbe)); + return(dbe->slot); } - return(-0x9b); + return(-0x96); /* we use out of memory here */ } static int find_base_entry(int volume, uint32 basehandle) +/* returns base_entry from volume/basehandle pair */ { int k=-1; DEV_NAMESPACE_MAP dnm; ino_t ino; if (!basehandle) return(-0x9b); - ino = nw_vol_handle_to_inode(volume, basehandle, &dnm); while (++k < anz_dbe) { @@ -500,8 +436,14 @@ static int find_base_entry(int volume, uint32 basehandle) if ( (DIR_BASE_ENTRY*)NULL != e && volume == e->nwpath.volume && ino == e->nwpath.statb.st_ino - && dnm.dev == e->nwpath.statb.st_dev) - return(k); + && dnm.dev == e->nwpath.statb.st_dev) { + if (!nwp_stat(&(e->nwpath), "find_base_entry")) { + return(touch_handle_entry_p(e)); + } else { /* the path has changed, we say handle is wrong */ + free_dbe_p(e); + return(-0x9b); + } + } } /* now we test whether it is the root of volume */ @@ -538,18 +480,27 @@ static int insert_get_base_entry(N_NW_PATH *nwpath, if (result) return(result); basehandle = name_2_base(nwpath, namespace, 0); } + if (basehandle) { int k=-1; while (++k < anz_dbe) { DIR_BASE_ENTRY *e=dir_base[k]; if ( (DIR_BASE_ENTRY*)NULL != e - && basehandle == e->basehandle - && nwpath->volume == e->nwpath.volume) - return(touch_handle_entry_p(e)); - } /* while */ + && nwpath->volume == e->nwpath.volume + && nwpath->statb.st_ino == e->nwpath.statb.st_ino + && nwpath->statb.st_dev == e->nwpath.statb.st_dev) { + if (nwp_stat(&(e->nwpath), "insert_get_base_entry")) { + /* the path has changed, we say handle is wrong */ + free_dbe_p(e); + } else { + return(touch_handle_entry_p(e)); + } + break; + } + } /* now i know that it's a new base entry */ return(add_dbe_entry(namespace, nwpath->volume, - basehandle, nwpath->path, &(nwpath->statb))); + basehandle, nwpath->path, &(nwpath->statb))); } return(-0xff); /* invalid path = -0x9c, -0xff no matching files */ } @@ -784,7 +735,7 @@ static int nw_init_search(int namespace, int result = build_base(namespace, nwp, pathes, 0, NULL); if (result > -1) { DIR_BASE_ENTRY *dbe=dir_base[result]; - result = base_open_seek_dir(dbe, 0L); + result = S_ISDIR(dbe->nwpath.statb.st_mode) ? 0 : -0xff; if (result > -1) { *responsedata++ = dbe->nwpath.volume; U32_TO_32(dbe->basehandle, responsedata); @@ -915,14 +866,23 @@ int nw_search_file_dir(int namespace, int datastream, { int result = find_base_entry(volume, basehandle); if (result > -1) { - DIR_BASE_ENTRY *dbe=dir_base[result]; - if ((result = base_open_seek_dir(dbe, sequence)) > -1) { - uint8 entry[256]; - struct dirent *dirbuff; - struct stat statb; - int dest_entry=-1; - DIR_SEARCH_STRUCT *ds=dbe->dir; - int vol_options = get_volume_options(volume, 0); + 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]; + struct dirent *dirbuff; + struct stat statb; + int dest_entry=-1; + int vol_options = get_volume_options(volume, 0); + ds->kpath = ds->unixname+strlen(ds->unixname); + *(ds->kpath) = '/'; + *(++(ds->kpath)) = '\0'; + if (sequence == MAX_U32) + sequence=0L; + if (sequence) + seekdir(ds->fdir, sequence); + dbe->locked++; strmaxcpy(entry, path, min(255, len)); @@ -938,11 +898,10 @@ int nw_search_file_dir(int namespace, int datastream, XDPRINTF((5,0,"nw_search_file_dir namspace=%d, searchpath='%s'", namespace, entry)); while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){ - if (dirbuff->d_ino) { - uint8 *name=(uint8*)(dirbuff->d_name); + 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)); + XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name)); if (namespace == NAME_DOS) { flag = (*name != '.' && fn_dos_match(name, entry, vol_options)); @@ -970,12 +929,16 @@ int nw_search_file_dir(int namespace, int datastream, 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)); + } } else { XDPRINTF((10, 0, "type = %s not ok searchattrib=0x%x", S_ISDIR(statb.st_mode) ? "DIR" :"FILE" ,searchattrib)); } } else { - XDPRINTF((5,0,"nw_search_file_dir stat error")); + XDPRINTF((1,0,"nw_search_file_dir: stat error fn='%s'", + ds->unixname)); } *(ds->kpath) = '\0'; } @@ -986,12 +949,11 @@ 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"); - sequence = (uint32) telldir(ds->fdir); *responsedata = (uint8) volume; responsedata++; U32_TO_32(basehandle, responsedata); responsedata+=4; - U32_TO_32(sequence, responsedata); + U32_TO_32((uint32)telldir(ds->fdir), responsedata); responsedata+=4; *responsedata = (uint8) 0; /* reserved */ responsedata++; @@ -1002,9 +964,10 @@ int nw_search_file_dir(int namespace, int datastream, } else result=-0xff; /* no files matching */ dbe->locked=0; - if (get_volume_options(dbe->nwpath.volume,1) & VOL_OPTION_REMOUNT) - free_dbe_dir(dbe); - } /* if result */ + closedir(ds->fdir); + } /* if NULL != ds->fdir */ + xfree(ds->unixname); + xfree(ds); } return(result); } @@ -1503,10 +1466,10 @@ int get_namespace_dir_entry(int volume, uint32 basehandle, build_dos_name(e, fname); if (S_ISDIR(e->nwpath.statb.st_mode)) { get_dos_dir_attrib(&(scif->u.d), &e->nwpath.statb, - fname); + e->nwpath.volume, fname); } else { get_dos_file_attrib(&(scif->u.f), &e->nwpath.statb, - fname); + e->nwpath.volume, fname); } return(sizeof(NW_SCAN_DIR_INFO)); } diff --git a/nwbind.c b/nwbind.c index 6693f3c..2abebc8 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "14-Aug-96" +#define REVISION_DATE "29-Aug-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -996,7 +996,14 @@ static void handle_fxx(int gelen, int func) obj.id = GET_BE32(rdata); result = nw_get_obj(&obj); if (!result) { - xdata->acces_level = obj.security; + /* don't know whether this is ok ?? */ + if (act_c->object_id == 1) { + xdata->acces_level = 0x33; + } else if (act_c->object_id == obj.id) { + xdata->acces_level = 0x22; + } else { + xdata->acces_level = 0x11; + } data_len = sizeof(struct XDATA); } else completition = (uint8)-result; } diff --git a/nwclient.c b/nwclient.c index 14a78f9..bf14f65 100644 --- a/nwclient.c +++ b/nwclient.c @@ -188,7 +188,7 @@ static int connection=0; #define RDATA(xdata, xfunc, xcomment) \ memcpy(requestdata, (xdata), sizeof(xdata)); \ ncp_request(0x2222, sequence, connection, 1, 0, \ - (xfunc), sizeof(data), (xcomment)) + (xfunc), sizeof(xdata), (xcomment)) #define ODATA(xfunc, xcomment) \ ncp_request(0x2222, sequence, connection, 1, 0, \ @@ -662,6 +662,15 @@ static void test3(void) } +static void test4(void) +{ + uint8 data[] = {0x0,0x2, 0x2c, 0x0,0x0}; + RDATA(data, 0x16, "test_0x16, 0x2c"); + if (!handle_event()) { + ; + } +} + static int do_5f(void) { uint8 data[] = {0x10, 0, 0, 0}; @@ -786,10 +795,12 @@ int main(int argc, char **argv) while (!scan_bindery_property(1, "NOBODY", "*", &lastid));; } get_volume_restriction_for_obj(1, 0); - +#if 0 test1(); +#endif test2(); test3(); + test4(); get_connection_info(0); get_connection_info(1); diff --git a/nwconn.c b/nwconn.c index 6494a15..00ea5c5 100644 --- a/nwconn.c +++ b/nwconn.c @@ -232,12 +232,12 @@ static int handle_ncp_serv(void) /* uint8 len = *(requestdata+1); */ uint8 *p = requestdata +2; if (0 == *p){ - /****** * SetDirektoryHandle *************/ + /******** SetDirektoryHandle *************/ struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ - uint8 target_dir_handle; /* Verzeichnis Handle zu „ndern */ - uint8 source_dir_handle; /* Verzeichnis Handle */ + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 target_dir_handle; /* to change */ + uint8 source_dir_handle; uint8 pathlen; uint8 path[2]; } *input = (struct INPUT *) (ncprequest); @@ -248,13 +248,12 @@ static int handle_ncp_serv(void) (int)input->pathlen, (int)(ncprequest->task)); - } else if (1 == *p){ /* liefert Verzeichnis Namen */ - /* Dir_handles */ + } else if (1 == *p){ /******** GetDirektoryPATH ***************/ struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ - uint8 dir_handle; /* Verzeichnis Handle */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; } *input = (struct INPUT *) (ncprequest); struct XDATA { uint8 len; @@ -271,7 +270,7 @@ static int handle_ncp_serv(void) /******** Scan Dir Info ****************/ struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 sub_dir_nmbr[2]; /* HI LOW */ /* firsttime 1 */ @@ -363,7 +362,7 @@ static int handle_ncp_serv(void) #if 0 struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_right_mask; @@ -457,7 +456,7 @@ static int handle_ncp_serv(void) #if 0 struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_right_mask; @@ -471,7 +470,7 @@ static int handle_ncp_serv(void) #if 0 struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 volume; uint8 dir_entry[2]; } *input = (struct INPUT *) (ncprequest); @@ -485,7 +484,7 @@ static int handle_ncp_serv(void) /* SCAN a Directory */ struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 attrib; /* Search Attrib z.B. 0x6 */ uint8 searchsequence[4]; /* 32 bit */ @@ -506,7 +505,7 @@ static int handle_ncp_serv(void) /* SCAN a root dir ???? */ struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 dont_know1; /* ???? 0xc0 */ uint8 dont_know2; /* ???? 0xfa */ @@ -576,7 +575,7 @@ static int handle_ncp_serv(void) #if 0 struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, typ */ + uint8 div[3]; /* 0x0, dlen, ufunc */ uint8 dir_handle; /* Verzeichnis Handle */ uint8 trustee_id[4]; /* Trustee Object ID */ uint8 trustee_right_mask; @@ -638,9 +637,9 @@ static int handle_ncp_serv(void) struct fs_usage fsp; memset(xdata, 0, sizeof(struct XDATA)); if (!nw_get_fs_usage(name, &fsp)) { - xdata->sec_per_block = 1; /* hard coded */ - U32_TO_32(fsp.fsu_blocks, xdata->total_blocks); - U32_TO_32(fsp.fsu_bavail, xdata->avail_blocks); + xdata->sec_per_block = 8; /* hard coded */ + U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); + U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); U32_TO_32(fsp.fsu_files, xdata->total_dirs); U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); } @@ -669,9 +668,9 @@ static int handle_ncp_serv(void) struct fs_usage fsp; memset(xdata, 0, sizeof(struct XDATA)); if (!nw_get_fs_usage(name, &fsp)) { - xdata->sec_per_block = 1; /* hard coded */ - U32_TO_32(fsp.fsu_blocks, xdata->total_blocks); - U32_TO_32(fsp.fsu_bavail, xdata->avail_blocks); + xdata->sec_per_block = 8; /* hard coded */ + U32_TO_32(fsp.fsu_blocks/8, xdata->total_blocks); + U32_TO_32(fsp.fsu_bavail/8, xdata->avail_blocks); U32_TO_32(fsp.fsu_files, xdata->total_dirs); U32_TO_32(fsp.fsu_ffree, xdata->avail_dirs); } @@ -1171,8 +1170,8 @@ static int handle_ncp_serv(void) uint8 max_size[2]; /* byte to readd */ } *input = (struct INPUT *)ncprequest; struct XDATA { - uint8 size[2]; /* read byzes */ - uint8 data[1072]; /* max data */ + uint8 size[2]; /* read bytes */ + uint8 data[2]; /* read data */ } *xdata=(struct XDATA*)responsedata; int fhandle = GET_BE32(input->fhandle); int max_size = GET_BE16(input->max_size); @@ -1182,8 +1181,6 @@ static int handle_ncp_serv(void) xdata->data+zusatz, max_size, offset); - - if (fhandle == test_handle) do_druck++; if (size > -1) { U16_TO_BE16(size, xdata->size); data_len=size+zusatz+2; @@ -1194,7 +1191,6 @@ static int handle_ncp_serv(void) case 0x49 : { /* write file */ struct INPUT { uint8 header[7]; /* Requestheader */ - uint8 filler; /* 0 Filler ?? */ uint8 ext_handle[2]; uint8 fhandle[4]; /* Dateihandle */ @@ -1209,7 +1205,6 @@ static int handle_ncp_serv(void) input->data, input_size, offset); - if (fhandle == test_handle) do_druck++; if (size < 0) completition = (uint8) -size; } diff --git a/nwdbm.c b/nwdbm.c index 99227d6..f9b5706 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 12-Jul-96 data base for mars_nwe */ +/* nwdbm.c 07-Sep-96 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -506,9 +506,9 @@ L1: return(result); } -int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) +static int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) { - int result = -0xea; /* no such member */ + int result = 0; /* we lie */ /* -0xea; /* no such member */ NETVAL val; if (!dbminit(FNVAL)){ key.dsize = NETVAL_KEY_SIZE; @@ -517,7 +517,7 @@ int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) val.prop_id = (uint8)prop_id; val.segment = (uint8)0; data = fetch(key); - while (result) { + while (1) { val.segment++; data = fetch(key); if (data.dptr != NULL) { @@ -961,7 +961,7 @@ uint32 nw_new_obj_prop(uint32 wanted_id, * and the property, * if propname == NULL only object will be created. * if valuesize == 0, then only obj or property - * will be created, returns obj-id + * will be created, returns obj->id */ { NETOBJ obj; @@ -994,6 +994,7 @@ typedef struct { uint8 pw_name[20]; } MYPASSWD; + static MYPASSWD *nw_getpwnam(uint32 obj_id) { static MYPASSWD pwstat; @@ -1309,19 +1310,9 @@ static void add_pr_queue(uint32 q_id, static void add_user_to_group(uint32 u_id, uint32 g_id) { - uint8 buff[4]; - U32_TO_BE32(g_id, buff); - /* Typ Flags Security */ - nw_new_obj_prop(u_id, NULL, 0x1 , 0x0, 0x33, - "GROUPS_I'M_IN", P_FL_SET, 0x31, - (char*)buff, 4); - - nw_new_add_prop_member(g_id, "GROUP_MEMBERS", u_id); - - nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 , - "SECURITY_EQUALS", P_FL_SET, 0x32, - (char*)buff, 4); - + nw_new_add_prop_member(u_id, "GROUPS_I'M_IN", g_id); + nw_new_add_prop_member(u_id, "SECURITY_EQUALS", g_id); + nw_new_add_prop_member(g_id, "GROUP_MEMBERS", u_id); } static void add_user_2_unx(uint32 u_id, char *unname) @@ -1337,7 +1328,7 @@ static void add_user_g(uint32 u_id, uint32 g_id, char *password, int dont_ch) { /* Typ Flags Security */ - if (nw_new_obj(&u_id, name, 0x1 , 0x0, (u_id == 1) ? 0x33 : 0x31) + if (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x31) && dont_ch) return; XDPRINTF((1, 0, "Add/Change User='%s', UnixUser='%s'", name, unname)); @@ -1557,8 +1548,30 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) upstr(auto_ins_passwd); while (NULL != (pw=getpwent())) { if (pw->pw_uid) { - if ( (pw->pw_passwd[0] != '*' && pw->pw_passwd[0] != 'x') - || pw->pw_passwd[1] != '\0') { + int do_add = ( (pw->pw_passwd[0]!= '*' && pw->pw_passwd[0]!='x') + || pw->pw_passwd[1] != '\0'); +#if SHADOW_PWD + /* + tip from: Herbert Rosmanith + */ + if (!do_add) { + struct spwd *sp=getspnam(pw->pw_name); + if (sp) { + if ( ((sp->sp_pwdp[0] != '*' && sp->sp_pwdp[0] != 'x') + || sp->sp_pwdp[1] !='\0') + && + ((sp->sp_pwdp[0] != 'N' && sp->sp_pwdp[1] != 'P') + || sp->sp_pwdp[2] != '\0') ) + do_add++; +#if 0 + XDPRINTF((1,0, "Shadow pw of %s = `%s`", pw->pw_name, sp->sp_pwdp)); +#endif + } else { + XDPRINTF((1,0, "cannot read shadow password")); + } + } +#endif + if ( do_add) { char nname[100]; xstrcpy(nname, pw->pw_name); upstr(nname); @@ -1650,7 +1663,7 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) /* dynamic or without name */ objs[anz++] = obj->id; if (anz == 10000) break; - } else if (obj->type == 1 && obj->id != 1 && obj->security != 0x31) { + } else if (obj->type == 1 /* && obj->id != 1 */ && obj->security != 0x31) { /* this is for correcting wrong obj security */ obj->security=0x31; (void)store(key, data); @@ -1683,6 +1696,268 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) return(anz); } + +#if 0 +#define MAX_OBJ_IDS 100000 /* should be enough */ +typedef struct { + int anz; + uint32 obj_ids[MAX_OBJ_IDS]; +} +#endif + + +static FILE *open_exp_file(char *path, int what_dbm, int mode) +/* mode 1 = export, 0 = import */ +{ + char buf[300]; + char *err_str="open_exp_file"; + FILE *f; + char *opmode=mode ? "w+" : "r"; + sprintf(buf, "%s/%s.exp", (path && *path) ? path : ".", + dbm_fn[what_dbm] ); + if (NULL == (f=fopen(buf, opmode))) { + errorp(0, err_str, "Open error `%s` mode=%s", buf, opmode); + } else { + if (!mode) { + sync_dbm(); + create_nw_db(dbm_fn[what_dbm], 1); + } + if (!dbminit(what_dbm)) + return(f); + else { + errorp(0, err_str, "dbminit error `%s`", buf); + fclose(f); + dbmclose(); + } + } + return(NULL); +} + + +static int export_obj(char *path) +{ + char *err_str="export_obj"; + int result = 1; + FILE *f = open_exp_file(path, FNOBJ, 1); + if (f != NULL) { + result=0; + for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { + data = fetch(key); + if (data.dptr) { + NETOBJ *o=(NETOBJ*)data.dptr; + fprintf(f, "0x%08x %-47s 0x%04x 0x%02x 0x%02x\n", + o->id, o->name, (int) o->type, + (int) o->flags, (int)o->security); + } + } + fclose(f); + dbmclose(); + } + return(result); +} + +static int export_prop(char *path) +{ + char *err_str="export_prop"; + int result = 1; + FILE *f = open_exp_file(path, FNPROP, 1); + if (f != NULL) { + result=0; + for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { + data = fetch(key); + if (data.dptr) { + NETPROP *p=(NETPROP*)data.dptr; + fprintf(f, "0x%08x 0x%02x %-15s 0x%02x 0x%02x\n", + p->obj_id, (int)p->id, p->name, + (int) p->flags, (int)p->security); + } + } + fclose(f); + dbmclose(); + } + return(result); +} + +static int export_val(char *path) +{ + char *err_str="export_val"; + int result = 1; + FILE *f = open_exp_file(path, FNVAL, 1); + if (f != NULL) { + result=0; + for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { + data = fetch(key); + if (data.dptr) { + NETVAL *v=(NETVAL*)data.dptr; + int k=128; + uint8 *p=v->value; + fprintf(f, "0x%08x 0x%02x 0x%02x ", + v->obj_id, (int)v->prop_id, (int) v->segment); + while (k--) { + fprintf(f, "%02x", (int)*p++); + } + fprintf(f, "\n"); + } + } + fclose(f); + dbmclose(); + } + return(result); +} + +int do_export_dbm(char *path) +/* Builds ASCII export files */ +{ + int result=export_obj(path); + if (!result) result=export_prop(path); + if (!result) result=export_val(path); + sync_dbm(); + return(result); +} + +static int import_obj(char *path) +{ + char *err_str="import_obj"; + int result=1; + FILE *f = open_exp_file(path, FNOBJ, 0); + if (f != NULL) { + char buff[300]; + int line=0; + result=0; + while (fgets(buff, sizeof(buff), f) != NULL){ + NETOBJ obj; + char name[300]; + int type; + int flags; + int security; + line++; + if (sscanf(buff, "%x %s %x %x %x", + &(obj.id), name, &type, + &flags, &security) == 5) { + strmaxcpy(obj.name, name, 47); + obj.type = (uint16)type; + obj.flags = (uint8) flags; + obj.security = (uint8) security; + key.dsize = NETOBJ_KEY_SIZE; + key.dptr = (char*)&obj; + data.dsize = sizeof(NETOBJ); + data.dptr = (char*)&obj; + if (store(key, data)) { + errorp(0, err_str, "Cannot store `%s` type=0x%x", + obj.name, (int)obj.type); + } + } else { + errorp(0, err_str, "Wrong line=%d: `%s`",line, buff); + } + } /* while */ + XDPRINTF((0, 0, "%s:got %d lines", err_str, line)); + fclose(f); + dbmclose(); + } + return(result); +} + +static int import_prop(char *path) +{ + char *err_str="import_prop"; + int result=1; + FILE *f = open_exp_file(path, FNPROP, 0); + if (f != NULL) { + char buff[300]; + int line=0; + result=0; + while (fgets(buff, sizeof(buff), f) != NULL){ + NETPROP prop; + int id; + char name[300]; + int type; + int flags; + int security; + line++; + if (sscanf(buff, "%x %x %s %x %x", + &(prop.obj_id), &id, name, &flags, &security) == 5) { + prop.id = (uint8)id; + strmaxcpy(prop.name, name, 15); + prop.flags = (uint8) flags; + prop.security = (uint8) security; + key.dsize = NETPROP_KEY_SIZE; + key.dptr = (char*)∝ + data.dsize = sizeof(NETPROP); + data.dptr = (char*)∝ + if (store(key, data)) { + errorp(0, err_str, "Cannot store `%s` obj_id=0x%x, prop_id=0x%x", + prop.name, prop.obj_id, (int)prop.id); + } + } else { + errorp(0, err_str, "Wrong line=%d: `%s`",line, buff); + } + } /* while */ + XDPRINTF((0, 0, "%s:got %d lines", err_str, line)); + fclose(f); + dbmclose(); + } + return(result); +} + +static int import_val(char *path) +{ + char *err_str="import_val"; + int result=1; + FILE *f = open_exp_file(path, FNVAL, 0); + if (f != NULL) { + char buff[300]; + int line=0; + result=0; + while (fgets(buff, sizeof(buff), f) != NULL){ + NETVAL val; + int prop_id; + int segment; + char value[300]; + line++; + if (sscanf(buff, "%x %x %x %s", + &(val.obj_id), &prop_id, &segment, value) == 4) { + uint8 *p=val.value; + uint8 *pp=value; + char smallbuf[3]; + int k=128; + smallbuf[2] = '\0'; + while (k--) { + int i; + memcpy(smallbuf, pp, 2); + pp+=2; + sscanf(smallbuf, "%x", &i); + *p++ = (uint8) i; + } + val.prop_id = (uint8) prop_id; + val.segment = (uint8) segment; + key.dsize = NETVAL_KEY_SIZE; + key.dptr = (char*)&val; + data.dsize = sizeof(NETVAL); + data.dptr = (char*)&val; + if (store(key, data)) { + errorp(0, err_str, "Cannot store obj_id=0x%8x, prop_id=0x%x", + val.obj_id, (int)val.prop_id); + } + } else { + errorp(0, err_str, "Wrong line=%d: `%s`",line, buff); + } + } /* while */ + XDPRINTF((0, 0, "%s:got %d lines", err_str, line)); + fclose(f); + dbmclose(); + } + return(result); +} + +int do_import_dbm(char *path) +/* Imports ASCII export files */ +{ + int result=import_obj(path); + if (!result) result=import_prop(path); + if (!result) result=import_val(path); + return(result); +} + /* ============> this should becomes queue.c or similar < ============== */ int nw_get_q_dirname(uint32 q_id, uint8 *buff) diff --git a/nwdbm.h b/nwdbm.h index f5ab8aa..9f21343 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -93,7 +93,6 @@ extern int nw_get_obj(NETOBJ *o); extern int prop_find_member(uint32 obj_id, int prop_id, uint32 member_id); extern int prop_add_member(uint32 obj_id, int prop_id, uint32 member_id); -extern int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id); extern int nw_get_prop_val_by_obj_id(uint32 obj_id, int segment_nr, diff --git a/nwfile.c b/nwfile.c index cd9c7c3..2a1eefb 100644 --- a/nwfile.c +++ b/nwfile.c @@ -56,7 +56,10 @@ static int new_file_handle(uint8 *unixname) if (anz_fhandles < MAX_FILE_HANDLES_CONN) { fh=&(file_handles[anz_fhandles]); rethandle = ++anz_fhandles; - } else return(0); /* no free handle anymore */ + } else { + XDPRINTF((1, 0, "No more free file handles")); + return(0); /* no free handle anymore */ + } } /* init handle */ fh->fd = -2; @@ -115,7 +118,7 @@ static int free_file_handle(int fhandle) void init_file_module(void) { - int k = -1; + int k = 0; while (k++ < anz_fhandles) free_file_handle(k); anz_fhandles = 0; } @@ -145,8 +148,8 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, * */ { - int fhandle=new_file_handle(unixname); - int dowrite = (access & 2) || creatmode ; + int fhandle = new_file_handle(unixname); + int dowrite = (access & 2) || creatmode; if (fhandle > 0){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); int completition = -0xff; /* no File Found */ @@ -157,19 +160,40 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, /* this is a PIPE Volume */ int statr = stat(fh->fname, stbuff); if (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) { - char pipecommand[300]; - char *topipe = "READ"; - if (creatmode) topipe = "CREAT"; - else if (dowrite) topipe = "WRITE"; - sprintf(pipecommand, "%s %s %d %d", - fh->fname, topipe, - act_connection, act_pid); - fh->f = ext_popen(pipecommand, geteuid(), getegid()); - fh->fd = (fh->f) ? fileno(fh->f->fildes[1]) : -1; - if (fh->fd > -1) { - fh->fh_flags |= FH_IS_PIPE; - fh->fh_flags |= FH_IS_PIPE_COMMAND; - if (!dowrite) stbuff->st_size = 0x7fffffff; + fh->fh_flags |= FH_IS_PIPE; + if (S_ISFIFO(stbuff->st_mode)){ + fh->fd = open(fh->fname, + O_NONBLOCK | dowrite ? O_RDWR : O_RDONLY); + } else { + int is_ok=0; + if (act_uid == stbuff->st_uid) { + if (stbuff->st_mode & S_IXUSR) { + stbuff->st_mode |= S_IWUSR; + is_ok++; + } + } else if (act_gid == stbuff->st_gid) { + if (stbuff->st_mode & S_IXGRP) { + stbuff->st_mode |= S_IWGRP; + is_ok++; + } + } else { + if (stbuff->st_mode & S_IXOTH) { + stbuff->st_mode |= S_IWOTH; + is_ok++; + } + } + if (is_ok) { + fh->fh_flags |= FH_IS_PIPE_COMMAND; + fh->fd=-3; + } else { + fh->fd=-1; + XDPRINTF((5, 0, "No PIPE command rights st_mode=0x%x uid=%d, gid=%d", + stbuff->st_uid, stbuff->st_gid)); + } + } + if (fh->fd != -1) { + if (!dowrite) stbuff->st_size = 0x7fff0000 | (rand() & 0xffff); + (void)time(&(stbuff->st_mtime)); if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; return(fhandle); } @@ -210,12 +234,14 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } } else { int statr = stat(fh->fname, stbuff); - int acm = (access & 2) ? (int) O_RDWR : (int)O_RDONLY; + int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY; if ( (!statr && !S_ISDIR(stbuff->st_mode)) || (statr && (acm & O_CREAT))){ if ((!statr) && 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)); } fh->fd = open(fh->fname, acm, 0777); XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); @@ -273,6 +299,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } else return(-0x81); /* no more File Handles */ } + int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) { if (fhandle > 0 && (--fhandle < anz_fhandles) ) { @@ -282,7 +309,7 @@ int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) fh->tmodi = nw_2_un_time(datum, zeit); return(0); } else return(-0x8c); - } + } else if (fh->fd == -3) return(0); } return(-0x88); /* wrong filehandle */ } @@ -294,7 +321,7 @@ int nw_close_datei(int fhandle, int reset_reuse) if (fhandle > 0 && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE); - if (fh->fd > -1) { + if (fh->fd > -1 || (fh->fd == -3 && fh->fh_flags & FH_IS_PIPE_COMMAND)) { int result = 0; int result2; if (fh->fh_flags & FH_IS_PIPE_COMMAND) { @@ -342,17 +369,38 @@ uint8 *file_get_unix_name(int fhandle) return(NULL); } +static void open_pipe_command(FILE_HANDLE *fh, int dowrite) +{ + if (NULL == fh->f) { + char pipecommand[512]; + sprintf(pipecommand, "%s %s %d %d", + fh->fname, + dowrite ? "WRITE" : "READ", + act_connection, act_pid); + fh->f = ext_popen(pipecommand, geteuid(), getegid()); + } + fh->fd = (fh->f) ? fileno(fh->f->fildes[dowrite ? 0 : 1]) : -3; +} + int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) { if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); + if (fh->fh_flags & FH_IS_PIPE_COMMAND) + open_pipe_command(fh, 0); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ - size = read(fh->fd, data, size); - if (size < 0) { - int k=5; - while (size < 0 && --k /* && errno == EAGAIN */) - size = read(fh->fd, data, size); + int readsize=size; + if (-1 == (size = read(fh->fd, data, readsize)) ) { + int k=2; + do { + sleep(1); + } while(k-- && -1 == (size = read(fh->fd, data, readsize))); + if (size == -1) size=0; + } + if (!size) { + if (fh->f->flags & 1) return(-0x57); + fh->f->flags |= 1; } } else { #if USE_MMAP @@ -393,9 +441,9 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) } if (size == -1) size=0; return(size); - } + } else if (fh->fd == -3) return(0); } - return(- 0x88); /* wrong filehandle */ + return(-0x88); /* wrong filehandle */ } int nw_seek_datei(int fhandle, int modus) @@ -404,7 +452,7 @@ int nw_seek_datei(int fhandle, int modus) FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ - return(0x7fffffff); + return(0x7fff0000 | (rand() & 0xffff) ); } else { int size=-0xfb; if (!modus) { @@ -413,7 +461,8 @@ int nw_seek_datei(int fhandle, int modus) } return(size); } - } + } else if (fh->fd == -3) return(0x7fff0000 | (rand() & 0xffff) ); + /* PIPE COMMAND */ } return(-0x88); /* wrong filehandle */ } @@ -423,6 +472,8 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) { if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); + if (fh->fh_flags & FH_IS_PIPE_COMMAND) + open_pipe_command(fh, 1); if (fh->fd > -1) { if (fh->fh_flags & FH_IS_READONLY) return(-0x94); if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ @@ -453,7 +504,7 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) return(result); } } - } + } else if (fh->fd == -3) return(0); } return(- 0x88); /* wrong filehandle */ } @@ -523,7 +574,7 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock) if (!result) return(0); else return(-0x21); /* LOCK Violation */ - } + } else if (fh->fd == -3) return(0); } return(-0x88); /* wrong filehandle */ } diff --git a/nwqueue.h b/nwqueue.h index eee5267..bf63b05 100644 --- a/nwqueue.h +++ b/nwqueue.h @@ -6,6 +6,7 @@ typedef struct { FILE *fildes[3]; /* filedescriptor to 0,1,2 of new process */ int command_pid; /* pid of piped command */ + int flags; /* special flags */ } FILE_PIPE; extern int ext_pclose(FILE_PIPE *fp); diff --git a/nwserv.c b/nwserv.c index 132911d..10c3302 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1226,6 +1226,9 @@ int main(int argc, char **argv) else return(usage(argv[0])); } +#if !DO_TESTING + chdir("/"); +#endif setgroups(0, NULL); init_tools(IN_PROG, init_mode); get_ini(1); diff --git a/nwvolume.c b/nwvolume.c index 012311b..20ae083 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -281,6 +281,14 @@ fsd.f_bavail = 1338518; fsd.f_files = 966656; fsd.f_ffree = 916066; fsd.f_bsize = 1024; +#elif 0 +/* test for other 'big' volume */ +fsd.f_blocks = 1783108; +fsd.f_bfree = 892839; +fsd.f_bavail = 800680; +fsd.f_files = 460800; +fsd.f_ffree = 415474; +fsd.f_bsize = 1024; #endif XDPRINTF((3, 0, "blocks=%d, bfree=%d, bavail=%d, files=%d, ffree=%d, bsize=%d",