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 0000000..0d074a5 Binary files /dev/null and b/examples/comm.exe differ 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",