mars_nwe-0.98.pl01

This commit is contained in:
Mario Fetka 2011-11-13 00:38:57 +01:00
parent 79edfdd7a3
commit 662f2651a2
26 changed files with 1382 additions and 558 deletions

View File

@ -21,7 +21,7 @@ all: rmeflag mk.li config.h nw.ini
echo ""; \
echo "********************************************************" ; \
echo ""; \
cat .mk.notes; rm .mk.notes ; \
cat .mk.notes; rm -f .mk.notes ; \
echo ""; \
echo "********************************************************" ; \
echo ""; echo "" ; fi ) fi
@ -41,6 +41,8 @@ install_ini: nw.ini
clean: mk.li nw.ini
./mk.li $@
rm -f .mk.notes
rm -f .eflag
distrib: mk.li nw.ini
./mk.li $@
@ -84,6 +86,7 @@ rmeflag:
@- rm -f .eflag
nw.ini: examples/nw.ini
@rm -f .mk.notes
@if [ -r $@ ] ; then echo "NOTE:examples/$@ is newer then $@" > .mk.notes ; \
echo "please compare examples/$@ with $@" >> .mk.notes; \
echo "make the changes you need and touch $@" >> .mk.notes; \

77
README
View File

@ -1,29 +1,100 @@
This is Mars_nwe, a free NetWare(tm) emulator for Linux and UnixWare,
written by Martin Stover, Marburg, Germany.
>>>> Please read THE WHOLE of this file as it gives important
>>>> information about mars_nwe, how you can get help and so on.
This software is freely distributable under the GNU public license, a
copy of which you should have received with this software (in a file
called COPYING).
WHAT CAN MARS_NWE DO?
=====================
Here is a very short list of what mars_nwe can do for you.
- mars_nwe is a very functional clone of a NetWare server that runs
under Linux. It works fine with the usual DOS client software that
normally comes with your NetWare server.
- mars_nwe offers file, bindery and print services for NetWare client
software.
- It was reported that if you patch your Linux kernel with the
speed-enhancing patch in examples/, mars_nwe is slower than NetWare
3.12, but FASTER THAN NetWare 4.1 on the same hardware.
- mars_nwe does not include any user license restrictions. You can
increase mars_nwe's licenses by simply recompiling it, and you can
start any number of mars_nwe's on your network!
- mars_nwe includes a RIP/SAP daemon that turns your Linux box into a
fine IPX router.
Related packages include:
- mars_dosutils: Some utilities that should free you from having to
use proprietary utilities when you want to use mars_nwe with DOS
clients.
- ncpfs: a linux-only filesystem allowing you to mount volumes
exported by NetWare servers on your linux box. This is included as
standard with Linux 2.0 and later.
FTP SITE
========
Martin Stover has no online internet site. New versions are always
sent by uuencoded mail to Volker Lendecke, who puts them on
ftp.gwdg.de:/pub/linux/misc/ncpfs. sunsite mirrors this directory in
sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs.
DOCUMENTATION
=============
There is not yet too much documentation available, look into the doc/
subdirectory. As Martin's native tongue is german, the documentation,
as well as a lot of the code comments are a mixture of english and
german. This will certainly converge to english in the future.
german. This will certainly converge to english in the future. Feel
free to increase the rate of convergence, see above for patches!
INSTALLATION
============
look in doc/INSTALL or doc/INSTALL.ger
HELP
====
To get help you can mail to and/or subscribe to LinWare mailing list:
Topics for the list:
- discussing LinWare server, its features, installation problems and bugs
- discussing mars_nwe server, its features, installation problems and bugs
- using IPX protocol under Linux
- IPX routing and router daemons under Linux
- mars_nwe
- and, last but not least, the LinWare daemon
You can subscribe to the list by sending command "add linware" in mail
message body to address: "listserv@sh.cvut.cz".
Your list postings should be sent to address: "linware@sh.cvut.cz".
CONTRIBUTIONS
=============
If you want to contribute to the development of the software then
please join the mailing list.
Martin accept patches (preferably in "diff -u" format) and is
always glad to receive feedback or suggestions.
Remember that free software of this kind lives or dies by the response
we get. If noone tells us they like it then we'll probably move onto
something else.

402
connect.c
View File

@ -1,4 +1,4 @@
/* connect.c 13-Jul-96 */
/* connect.c 09-Aug-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -28,9 +28,6 @@
static int test_handle=-1;
#endif
#define DONT_KNOW_IF_OK 0
static int default_uid=-1;
static int default_gid=-1;
@ -81,7 +78,6 @@ static char *build_unix_name(NW_PATH *nwpath, int modus)
*p = '\0';
}
}
if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT) downstr((uint8*)pp);
return(unixname);
}
@ -92,62 +88,60 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
*/
{
int rethandle;
DIR_HANDLE *fh = NULL;
DIR_HANDLE *dh = NULL;
time_t akttime = time(NULL);
time_t last_time = akttime;
int thandle = 0;
int nhandle = 0;
for (rethandle=0; rethandle < anz_dirhandles; rethandle++){
fh=&(dir_handles[rethandle]);
if (!fh->inode) {
dh=&(dir_handles[rethandle]);
if (!dh->inode) {
if (!nhandle) nhandle = rethandle+1;
} else if (fh->inode == inode && fh->volume == nwpath->volume){
} else if (dh->inode == inode && dh->volume == nwpath->volume){
/* Dieser hat Vorrang */
if (fh->f) closedir(fh->f);
fh->f = NULL;
fh->timestamp = akttime;
if (dh->f) closedir(dh->f);
dh->f = NULL;
dh->timestamp = akttime;
nhandle = rethandle+1;
break;
} else if (fh->timestamp < last_time){
} else if (dh->timestamp < last_time){
thandle = rethandle+1;
last_time = fh->timestamp;
last_time = dh->timestamp;
}
}
if (!nhandle){
if (anz_dirhandles < MAX_DIRHANDLES) {
fh=&(dir_handles[anz_dirhandles]);
dh=&(dir_handles[anz_dirhandles]);
rethandle = ++anz_dirhandles;
} else {
fh=&(dir_handles[thandle-1]);
if (fh->f) closedir(fh->f);
fh->f = NULL;
dh=&(dir_handles[thandle-1]);
if (dh->f) closedir(dh->f);
dh->f = NULL;
rethandle = thandle;
}
} else rethandle=nhandle;
/* init dir_handle */
fh=&(dir_handles[rethandle-1]);
strcpy(fh->unixname, build_unix_name(nwpath, 0));
if ((fh->f = opendir(fh->unixname)) != (DIR*) NULL){
fh->kpath = fh->unixname + strlen(fh->unixname);
fh->volume = nwpath->volume;
fh->vol_options = nw_volumes[fh->volume].options;
fh->inode = inode;
fh->timestamp = akttime;
fh->sequence = 0;
fh->dirpos = (off_t)0;
if (fh->vol_options & VOL_OPTION_REMOUNT) {
closedir(fh->f);
fh->f = NULL;
dh=&(dir_handles[rethandle-1]);
strcpy(dh->unixname, build_unix_name(nwpath, 0));
dh->kpath = dh->unixname + strlen(dh->unixname);
if ((dh->f = opendir(dh->unixname)) != (DIR*) NULL){
dh->volume = nwpath->volume;
dh->vol_options = nw_volumes[dh->volume].options;
dh->inode = inode;
dh->timestamp = akttime;
dh->sequence = 0;
dh->dirpos = (off_t)0;
if (dh->vol_options & VOL_OPTION_REMOUNT) {
closedir(dh->f);
dh->f = NULL;
}
} else {
fh->f = (DIR*)NULL;
fh->unixname[0] = '\0';
fh->vol_options = 0;
fh->kpath = (char*)NULL;
rethandle = -0x9c;
dh->f = (DIR*)NULL;
dh->unixname[0] = '\0';
dh->vol_options = 0;
dh->kpath = (char*)NULL;
rethandle = /* -0x9c */ -0xff;
}
return(rethandle);
}
@ -155,12 +149,12 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
static int free_dir_handle(int dhandle)
{
if (dhandle > 0 && --dhandle < anz_dirhandles) {
DIR_HANDLE *fh=&(dir_handles[dhandle]);
if (fh->f != (DIR*) NULL) {
closedir(fh->f);
fh->f = (DIR*)NULL;
DIR_HANDLE *dh=&(dir_handles[dhandle]);
if (dh->f != (DIR*) NULL) {
closedir(dh->f);
dh->f = (DIR*)NULL;
}
fh->inode = 0;
dh->inode = 0;
while (anz_dirhandles && !dir_handles[anz_dirhandles-1].inode)
anz_dirhandles--;
return(0);
@ -183,27 +177,23 @@ void set_default_guid(void)
void set_guid(int gid, int uid)
{
char aktname[100];
if (gid > -1 && uid > -1) {
seteuid(uid);
cuserid(aktname);
} else aktname[0] = '\0';
if ( gid < 0 || uid < 0
|| seteuid(0)
|| setegid(gid) == -1
|| seteuid(uid) == -1 ) {
DPRINTF(("SET GID=%d, UID=%d failed\n", gid, uid));
|| setegid(gid)
|| seteuid(uid) ) {
set_default_guid();
} else {
if (aktname[0]) {
struct passwd *pw = getpwuid(uid);
if (NULL != pw) {
seteuid(0);
initgroups(aktname, gid);
if (seteuid(uid) == -1) set_default_guid();
initgroups(pw->pw_name, gid);
}
XDPRINTF((5,0,"SET GID=%d, UID=%d OK", gid, uid));
act_gid = gid;
act_uid = uid;
if (seteuid(uid)) set_default_guid();
}
XDPRINTF((5,0,"SET GID=%d, UID=%d %s", gid, uid,
(gid==act_gid && uid == act_uid) ? "OK" : "failed"));
}
static char *conn_get_nwpath_name(NW_PATH *p)
@ -218,7 +208,7 @@ static char nwpathname[300];
return(nwpathname);
}
static int x_str_match(uint8 *s, uint8 *p)
static int x_str_match(uint8 *s, uint8 *p, int soptions)
{
uint8 pc, sc;
uint state = 0;
@ -256,7 +246,7 @@ static int x_str_match(uint8 *s, uint8 *p)
case '*' : if (!*p) return(1); /* last star */
while (*s) {
if (x_str_match(s, p) == 1) return(1);
if (x_str_match(s, p, soptions) == 1) return(1);
else if (*s == '.') return(0);
++s;
}
@ -270,7 +260,13 @@ static int x_str_match(uint8 *s, uint8 *p)
state = 100;
continue;
default : if (pc != *s++) return(0); /* normal char */
default : /* 'normal' chars */
if (soptions & VOL_OPTION_IGNCASE) {
if (*s != pc && ((!isalpha(pc)) || (!isalpha(*s))
|| (pc | 0x20) != (*s | 0x20)))
return(0);
} else if (pc != *s) return(0);
s++;
break;
} /* switch */
@ -317,10 +313,11 @@ static int x_str_match(uint8 *s, uint8 *p)
default : break;
} /* switch */
} /* while */
if (*s=='.' && *(s+1)=='\0') return(1); /* I hope this is right */
return ( (*s) ? 0 : 1);
}
int fn_match(uint8 *s, uint8 *p, int options)
int fn_dos_match(uint8 *s, uint8 *p, int options)
{
uint8 *ss=s;
int len=0;
@ -332,14 +329,18 @@ int fn_match(uint8 *s, uint8 *p, int options)
} else {
++len;
if ((pf && len > 3) || len > 8) return(0);
if (!(options & VOL_OPTION_IGNCASE)){
if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */
if (*ss >= 'A' && *ss <= 'Z') return(0);
} else { /* only upshift chars */
if (*ss >= 'a' && *ss <= 'z') return(0);
}
}
}
return(x_str_match(s, p));
}
return(x_str_match(s, p, options));
}
typedef struct {
@ -370,7 +371,9 @@ static int func_search_entry(NW_PATH *nwpath, int attrib,
if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */
else soptions = nw_volumes[volume].options;
strcpy((char*)entry, (char*)nwpath->fn);
#if 0
if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */
#endif
nwpath->fn[0] = '\0';
strcpy(xkpath, build_unix_name(nwpath, 1|2));
@ -386,7 +389,7 @@ static int func_search_entry(NW_PATH *nwpath, int attrib,
okflag = (name[0] != '.' &&
( (entry[0] == '*' && entry[1] == '\0')
|| (!strcmp((char*)name, (char*)entry))
|| fn_match(name, entry, soptions)));
|| fn_dos_match(name, entry, soptions)));
if (okflag) {
*kpath = '\0';
strcpy(kpath, (char*)name);
@ -395,7 +398,9 @@ 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;
@ -429,8 +434,9 @@ static int get_dir_entry(NW_PATH *nwpath,
if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */
else soptions = nw_volumes[volume].options;
strcpy((char*)entry, (char*)nwpath->fn);
#if 0
if (soptions & VOL_OPTION_DOWNSHIFT) downstr(entry); /* now downshift chars */
#endif
nwpath->fn[0] = '\0';
strcpy(xkpath, build_unix_name(nwpath, 1|2));
XDPRINTF((5,0,"get_dir_entry attrib=0x%x path:%s:, xkpath:%s:, entry:%s:",
@ -456,7 +462,7 @@ static int get_dir_entry(NW_PATH *nwpath,
okflag = (name[0] != '.' &&
( (entry[0] == '*' && entry[1] == '\0')
|| (!strcmp((char*)name, (char*)entry))
|| fn_match(name, entry, soptions)));
|| fn_dos_match(name, entry, soptions)));
if (okflag) {
*kpath = '\0';
strcpy(kpath, (char*)name);
@ -465,7 +471,9 @@ 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 */
}
@ -511,8 +519,9 @@ static int get_dh_entry(DIR_HANDLE *dh,
struct dirent *dirbuff;
uint8 entry[256];
strmaxcpy(entry, search, 255);
#if 0
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry);
#endif
if ( (uint16)*sequence == MAX_U16) *sequence = 0;
if (*sequence < dh->sequence) {
@ -532,7 +541,7 @@ static int get_dh_entry(DIR_HANDLE *dh,
}
dh->dirpos = telldir(f);
}
XDPRINTF((5,0,"get_dh_entry seq=x%x, attrib=0x%x path:%s:, entry:%s:",
XDPRINTF((5,0,"get_dh_entry seq=0x%x, attrib=0x%x path:%s:, entry:%s:",
*sequence, attrib, dh->unixname, entry));
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
@ -543,7 +552,7 @@ static int get_dh_entry(DIR_HANDLE *dh,
okflag = (name[0] != '.' && (
(!strcmp((char*)name, (char*)entry)) ||
(entry[0] == '*' && entry[1] == '\0')
|| fn_match(name, entry, dh->vol_options)));
|| fn_dos_match(name, entry, dh->vol_options)));
if (okflag) {
strcpy(dh->kpath, (char*)name);
@ -555,19 +564,19 @@ 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;
}
} /* if */
} /* while */
dh->kpath[0] = '\0';
*sequence = dh->sequence;
dh->dirpos = telldir(f);
release_dh_f(dh);
} /* if */
return(okflag);
}
@ -587,9 +596,12 @@ static void conn_build_path_fn( uint8 *vol,
*has_wild = 0; /* no wild char */
while (len-- && *data){
if (*data == 0xae) *p1++ = '.';
#if 0
else if (*data > 0x60 && *data < 0x7b) {
*p1++ = *data - 0x20; /* all is upshift */
} else if (*data == 0xaa|| *data == '*' ) {
}
#endif
else if (*data == 0xaa|| *data == '*' ) {
*p1++ = '*';
(*has_wild)++;
} else if (*data == 0xbf|| *data == '?' ) {
@ -602,6 +614,7 @@ static void conn_build_path_fn( uint8 *vol,
int len = (int) (p1 - path);
memcpy(vol, path, len);
vol[len] = '\0';
upstr(vol);
p1 = path;
} else *p1++ = *data;
data++;
@ -645,6 +658,13 @@ static int build_path( NW_PATH *path,
while (j--) {
if (!strcmp((char*)nw_volumes[j].sysname, (char*)vol)) {
path->volume = j;
if (nw_volumes[j].options & VOL_OPTION_DOWNSHIFT) {
downstr(path->path);
downstr(path->fn);
} else {
upstr(path->path);
upstr(path->fn);
}
break;
}
}
@ -700,7 +720,6 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
strcpy((char*)nwpath->path, (char*)dirs[dir_handle].path);
} else return(-0x9b); /* wrong dir handle */
}
if (*p) {
uint8 *panf = nwpath->path;
uint8 *p1 = panf+strlen((char*)panf);
@ -758,13 +777,37 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
}
}
}
if (!completition) completition = nw_path_ok(nwpath);
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(nwpath->fn);
} else {
upstr(nwpath->path);
upstr(nwpath->fn);
}
if (v->options & VOL_OPTION_IGNCASE) {
uint8 unixname[1024]; /* should be enough */
uint8 *pp=unixname+v->unixnamlen;
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);
mangle_dos_name(v, unixname, pp);
XDPRINTF((5, 0, "Mangled DOS/unixname=%s", unixname));
memcpy(nwpath->path, pp, pathlen);
if (fnlen)
memcpy(nwpath->fn, pp+pathlen, fnlen);
}
} else return(-0x98); /* wrong volume */
completition = nw_path_ok(nwpath);
}
return(completition);
}
#if DONT_KNOW_IF_OK
static int lastdirhandle=0;
#endif
int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
uint8 *data, int len, int only_dir)
/*
@ -772,16 +815,9 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle,
* else a negativ errcode will be returned
*/
{
int completition;
#if DONT_KNOW_IF_OK
if (!dirhandle && len > 1 && *data== ':' && *(data+1) == '/') {
--len;
data++;
dirhandle = lastdirhandle;
} else if (dirhandle) lastdirhandle = dirhandle;
#endif
completition = build_path(nwpath, data, len, only_dir);
XDPRINTF((5, 0, "conn_get_kpl_path %s", conn_get_nwpath_name(nwpath)));
int completition = build_path(nwpath, data, len, only_dir);
XDPRINTF((5, 0, "compl=0x%x, conn_get_kpl_path %s",
completition, conn_get_nwpath_name(nwpath)));
if (!completition) completition = build_verz_name(nwpath, dirhandle);
return(completition);
}
@ -905,6 +941,8 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
NW_PATH *nwpath)
{
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);
XDPRINTF((5,0, "get_file_attrib = 0x%x of ,%s, uid=%d, gid=%d",
(int)f->attrib, conn_get_nwpath_name(nwpath),
@ -923,7 +961,8 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb,
{
XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath)));
strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name));
d->attrib=0; /* d->name could be too long */
upstr(d->name);
d->attrib = 0x10; /* Verzeichnis */
d->ext_attrib = 0xff; /* effektive rights ?? */
un_date_2_nw(stb->st_mtime, d->create_date, 1);
@ -1010,13 +1049,6 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len,
struct stat stbuff;
int completition=-0x9c;
NW_PATH nwpath;
#if DONT_KNOW_IF_OK
if (!dir_handle && len > 1 && *data== ':' && *(data+1) == '/') {
--len;
data++;
dir_handle = lastdirhandle;
} else if (dir_handle) lastdirhandle = dir_handle;
#endif
build_path(&nwpath, data, len, 0);
if (nwpath.fn[0] != '.') { /* Files with . at the beginning are not ok */
completition = build_verz_name(&nwpath, dir_handle);
@ -1048,10 +1080,10 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
} else { /* rmdir */
int j = -1;
while (++j < (int)anz_dirhandles){
DIR_HANDLE *fh=&(dir_handles[j]);
if (fh->inode == completition && fh->f != (DIR*) NULL) {
closedir(fh->f);
fh->f = (DIR*)NULL;
DIR_HANDLE *dh=&(dir_handles[j]);
if (dh->inode == completition && dh->f != (DIR*) NULL) {
closedir(dh->f);
dh->f = (DIR*)NULL;
}
}
XDPRINTF((5,0,"RMDIR dirname:%s:", unname));
@ -1065,8 +1097,8 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode)
}
j = -1;
while (++j < (int)anz_dirhandles){
DIR_HANDLE *fh=&(dir_handles[j]);
if (fh->inode == completition) free_dir_handle(j+1);
DIR_HANDLE *dh=&(dir_handles[j]);
if (dh->inode == completition) free_dir_handle(j+1);
}
completition = 0;
} else if (errno == EEXIST)
@ -1163,7 +1195,20 @@ static int change_dir_entry( NW_DIR *dir, int volume,
int new_entry, int task)
{
if (new_entry || (dir->inode && dir->is_temp != 2)) {
new_str(dir->path, path);
int len=strlen(path);
if (dir->path) xfree(dir->path);
dir->path=xmalloc(len+2);
if (len) {
memcpy(dir->path, path, len);
if (dir->path[len-1] != '/') {
*(dir->path + len) = '/';
++len;
}
} else {
*(dir->path) = '/';
++len;
}
*(dir->path+len) = '\0';
dir->inode = inode;
dir->volume = (uint8) volume;
dir->timestamp = time(NULL);
@ -1360,6 +1405,11 @@ int nw_dir_search(uint8 *info,
if (dirhandle > 0 && --dirhandle < anz_dirhandles){
DIR_HANDLE *dh = &(dir_handles[dirhandle]);
struct stat stbuff;
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) {
downstr(nwpath.fn);
} else {
upstr(nwpath.fn);
}
if (get_dh_entry(dh,
nwpath.fn,
&searchsequence,
@ -1417,8 +1467,8 @@ int nw_open_dir_handle( int dir_handle,
completition = new_dir_handle((ino_t)completition, &nwpath);
if (completition > -1) {
DIR_HANDLE *fh = &(dir_handles[completition-1]);
*volume = fh->volume;
DIR_HANDLE *dh = &(dir_handles[completition-1]);
*volume = dh->volume;
*dir_id = completition;
*searchsequence = MAX_U16;
completition = 0xff; /* all rights */
@ -1558,11 +1608,18 @@ static int s_nw_scan_dir_info(int dir_handle,
uint8 dirname[256];
if (!dirsequenz) dirsequenz++;
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) {
downstr(wild);
} else {
upstr(wild);
}
strcpy((char*)dirname, (char*)wild);
XDPRINTF((5,0,"SCAN_DIR: rights = 0x%x, subnr = %d",
(int)rights, (int)GET_BE16(subnr)));
if (*dirname) {
while ( get_dh_entry( dh,
dirname,
&searchsequence,
@ -1572,6 +1629,7 @@ static int s_nw_scan_dir_info(int dir_handle,
XDPRINTF((5,0,"SCAN_DIR: von %s, found %s:", dh->unixname, dirname));
if (++aktsequenz == dirsequenz) { /* actual found */
U16_TO_BE16(aktsequenz, subnr);
upstr(dirname);
strncpy((char*)subname, (char*)dirname, 16);
U32_TO_BE32(1L, owner); /* erstmal */
un_date_2_nw(stbuff.st_mtime, subdatetime, 1);
@ -1581,7 +1639,8 @@ static int s_nw_scan_dir_info(int dir_handle,
strcpy((char*)dirname, (char*)wild);
} /* while */
} else {
strcpy(dh->kpath, ".");
*(dh->kpath) = '.';
*(dh->kpath+1) = '\0';
if (!stat(dh->unixname, &stbuff)) {
U16_TO_BE16(1, subnr);
memset(subname, 0, 16);
@ -1622,43 +1681,20 @@ int nw_scan_dir_info(int dir_handle, uint8 *data, int len, uint8 *subnr,
}
typedef struct {
uint8 time[2];
uint8 date[2];
uint8 id[4];
} NW_FILE_DATES_INFO;
typedef struct {
uint8 subdir[4];
uint8 attributes[4]; /* 0x20,0,0,0 File */
uint8 uniqueid; /* 0 */
uint8 flags; /* 0x18 */
uint8 namespace; /* 0 */
uint8 namlen;
uint8 name[12];
NW_FILE_DATES_INFO created;
NW_FILE_DATES_INFO archived;
NW_FILE_DATES_INFO updated;
uint8 size[4];
uint8 reserved_1[44];
uint8 inherited_rights_mask[2];
uint8 last_access_date[2];
uint8 reserved_2[28];
} NW_DOS_FILE_INFO;
static void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
struct stat *stb,
NW_PATH *nwpath)
uint8 *path)
{
f->namlen=min(strlen((char*)nwpath->fn), 12);
strncpy((char*)f->name, (char*)nwpath->fn, f->namlen);
uint8 spath[14];
f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12);
upstr(spath);
strncpy((char*)f->name, (char*)spath, f->namlen);
/* Attribute */
/* 0x20 Archive Flag */
/* 0x80 Sharable */
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
XDPRINTF((5,0, "get_dos_file_attrib = 0x%x of ,%s, uid=%d, gid=%d",
(int)f->attributes[0], conn_get_nwpath_name(nwpath),
stb->st_uid, stb->st_gid));
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);
@ -1667,32 +1703,15 @@ static void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
U32_TO_32(stb->st_size, f->size);
}
typedef struct {
uint8 subdir[4];
uint8 attributes[4]; /* 0x10,0,0,0 DIR */
uint8 uniqueid; /* 0 */
uint8 flags; /* 0x14 or 0x1c */
uint8 namespace; /* 0 */
uint8 namlen;
uint8 name[12];
NW_FILE_DATES_INFO created;
NW_FILE_DATES_INFO archived;
uint8 modify_time[2];
uint8 modify_date[2];
uint8 next_trustee[4];
uint8 reserved_1[48];
uint8 max_space[4];
uint8 inherited_rights_mask[2];
uint8 reserved_2[26];
} NW_DOS_DIR_INFO;
static void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
struct stat *stb,
NW_PATH *nwpath)
uint8 *path)
{
f->namlen=min(strlen((char*)nwpath->fn), 12);
strncpy((char*)f->name, (char*)nwpath->fn, f->namlen);
uint8 spath[14];
f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12);
upstr(spath);
strncpy((char*)f->name, (char*)spath, f->namlen);
f->attributes[0] = 0x10; /* Dir */
un_date_2_nw(stb->st_mtime, f->created.date,0);
un_time_2_nw(stb->st_mtime, f->created.time,0);
@ -1702,13 +1721,6 @@ static void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
U32_TO_BE32(MAX_U32, f->max_space);
}
typedef struct {
uint8 searchsequence[4];
union {
NW_DOS_DIR_INFO d;
NW_DOS_FILE_INFO f;
} u;
} NW_SCAN_DIR_INFO;
int nw_scan_a_directory(uint8 *rdata,
int dirhandle,
@ -1733,12 +1745,16 @@ int nw_scan_a_directory(uint8 *rdata,
memset(rdata, 0, sizeof(NW_SCAN_DIR_INFO));
U32_TO_BE32((uint32)searchsequence, scif->searchsequence);
XDPRINTF((5,0, "nw_scan_a_directory = %s, uid=%d, gid=%d",
conn_get_nwpath_name(&nwpath),
stbuff.st_uid, stbuff.st_gid));
if ( (stbuff.st_mode & S_IFMT) == S_IFDIR) {
get_dos_dir_attrib(&(scif->u.d), &stbuff,
&nwpath);
nwpath.fn);
} else {
get_dos_file_attrib(&(scif->u.f), &stbuff,
&nwpath);
nwpath.fn);
}
return(sizeof(NW_SCAN_DIR_INFO));
} else return(-0xff); /* not found */
@ -1758,11 +1774,65 @@ 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);
get_dos_dir_attrib(d, &stbuff, nwpath.fn);
return(sizeof(NW_DOS_DIR_INFO));
} else return(-0xff); /* not found */
} else return(completition); /* wrong path */
}
static int my_match(uint8 *s, uint8 *p)
{
int len=0;
int dot=0;
for (; *s && *p; s++,p++) {
if (len == 12) return(0);
if (*s == '.') {
if (dot) return(0);
dot++;
} else if (dot) {
if (dot++ > 3) return(0);
} else if (len == 8) return(0);
if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s))
|| (*p | 0x20) != (*s | 0x20)))
return(0);
++len;
}
return( ((!*s) && (*p=='/' || *p == '\0')) ? len : 0);
}
static int get_match(uint8 *unixname, uint8 *p)
{
DIR *d;
if (!p || !*p) return(1);
*p = '\0';
if (NULL != (d=opendir(unixname))) {
struct dirent *dirbuff;
XDPRINTF((10, 0, "opendir OK unixname='%s' p='%s'", unixname, p+1));
*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);
XDPRINTF((10, 0, "get match, match OK"));
closedir(d);
return(get_match(unixname, p+1+len));
}
}
}
closedir(d);
} else {
XDPRINTF((2, 0, "DOS get_match opendir failed unixname='%s'", unixname));
*p='/';
}
return(0);
}
void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp)
{
get_match(unixname, pp-1);
}

View File

@ -1,4 +1,4 @@
/* connect.h 04-May-96 */
/* connect.h 28-Jul-96 */
#ifndef _CONNECT_H_
#define _CONNECT_H_
typedef struct {
@ -55,6 +55,57 @@ typedef struct {
} NW_DIR_INFO;
typedef struct {
uint8 time[2];
uint8 date[2];
uint8 id[4];
} NW_FILE_DATES_INFO;
typedef struct {
uint8 subdir[4];
uint8 attributes[4]; /* 0x20,0,0,0 File */
uint8 uniqueid; /* 0 */
uint8 flags; /* 0x18 */
uint8 namespace; /* 0 */
uint8 namlen;
uint8 name[12];
NW_FILE_DATES_INFO created;
NW_FILE_DATES_INFO archived;
NW_FILE_DATES_INFO updated;
uint8 size[4];
uint8 reserved_1[44];
uint8 inherited_rights_mask[2];
uint8 last_access_date[2];
uint8 reserved_2[28];
} NW_DOS_FILE_INFO;
typedef struct {
uint8 subdir[4];
uint8 attributes[4]; /* 0x10,0,0,0 DIR */
uint8 uniqueid; /* 0 */
uint8 flags; /* 0x14 or 0x1c */
uint8 namespace; /* 0 */
uint8 namlen;
uint8 name[12];
NW_FILE_DATES_INFO created;
NW_FILE_DATES_INFO archived;
uint8 modify_time[2];
uint8 modify_date[2];
uint8 next_trustee[4];
uint8 reserved_1[48];
uint8 max_space[4];
uint8 inherited_rights_mask[2];
uint8 reserved_2[26];
} NW_DOS_DIR_INFO;
typedef struct {
uint8 searchsequence[4];
union {
NW_DOS_DIR_INFO d;
NW_DOS_FILE_INFO f;
} u;
} NW_SCAN_DIR_INFO;
extern int nw_init_connect(void);
extern void nw_exit_connect(void);
@ -130,6 +181,15 @@ extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len,
uint8 *subdatetime, uint8 *owner);
extern void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
struct stat *stb,
uint8 *path);
void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
struct stat *stb,
uint8 *path);
#define MAX_NW_DIRS 255
extern NW_DIR dirs[MAX_NW_DIRS];
extern int used_dirs;
@ -154,11 +214,15 @@ extern int nw_scan_a_root_dir(uint8 *rdata,
int dirhandle);
extern int fn_match(uint8 *s, uint8 *p, int options);
extern int fn_dos_match(uint8 *s, uint8 *p, int options);
extern void un_date_2_nw(time_t time, uint8 *d, int high_low);
extern time_t nw_2_un_time(uint8 *d, uint8 *t);
extern void un_time_2_nw(time_t time, uint8 *d, int high_low);
extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp);
#endif

View File

@ -163,6 +163,8 @@ Erste 'oeffentliche' Version
- Dummy Routinen fuer OS/2 extended attributes eingebaut.
- NFS-namespace rudimentaer eingebaut.
<----- ^^^^^^^^^^ pl0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- bessere OS2 Nameunterstuetzung.
- 0x17 0x81 als Dummy implementiert fuer Windows Client.
<----- ^^^^^^^^^^ pl1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -17,7 +17,7 @@ Ales Dryak <A.Dryak@sh.cvut.cz>
his linware gave the kick
Fritz Elfert <fritz@wuemaus.franken.de>
gives Bugreport and Patches
gives bugreport and patches
Ruedi Kneubuehler <pingu@satu.baboon.ch>
helping and testing for linux/sparc
@ -31,6 +31,9 @@ James B. MacLean <macleajb@ednet.ns.ca>
Jiri A. Randus <Jiri.Randus@vslib.cz>
testing bindery code
Gregory Steuck <greg@nsu.ru>
testings and errorreports
Winfried Truemper <truemper@mi.uni-koeln.de>:
re-wrote `INSTALL' and added explanations to `nw.ini'

View File

@ -1,4 +1,6 @@
# in this files are important notes for user of mars_nwe.
# in this files are some notes for user of mars_nwe.
------30-Jul-96--- 0.98.pl1 ----------
- better OS2 name handling (upper/lowercase)
------22-Jul-96--- 0.98.pl0 ----------
- problems with directory handles eliminated.
(missunderstood 'creat permanent directory handle' call :( )

View File

@ -1,7 +1,7 @@
Begin3
Title: mars_nwe
Version: 0.98
Entered-date: 22-Jul-96
Version: 0.98.pl1
Entered-date: 14-Aug-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.tgz
165kB mars_nwe-0.98.pl1.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

View File

@ -43,7 +43,7 @@
/* <--------------------------------------------------------------------> */
#define MAX_NW_VOLS 10 /* max. number of mars_nwe-volumes */
#define MAX_FILE_HANDLES_CONN 80 /* max. number of open files per */
#define MAX_FILE_HANDLES_CONN 255 /* max. number of open files per */
/* connection */
/* <--------------- new namespace services call -----------------------> */
#define MAX_DIR_BASE_ENTRIES 50 /* max. cached base entries per */

View File

@ -59,8 +59,12 @@
# individual home-directory
#
# OPTIONS: none or some of the following characters (without a seperator)
# k allow lowercase-filenames (if you don't set this, all
# files _must_ be upper-case)
#
# Next two options control DOS and OS/2 namespace.
# i ignore case, handle mixing upper/lowercase filenames (slow)
# k use lowercase-filenames (if you don't set this,
# and you don't set 'i' all files _must_ be upper-case)
#
# m removable volume (e.g. cd-roms)
# r volume is read-only and always reports "0 byte free"
# (this is intended for copies of CD-ROMs on harddisks)
@ -72,6 +76,7 @@
# p "PIPE"-filesystem. All files are pipe commands.
# See `doc/PIPE-FS'.
#
# additional Namespaces
# O + OS/2 namespace.
# N + NFS namespace.
# -------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
#if 0
#makefile.unx 12-Jul-96
#makefile.unx 28-Jul-96
#endif
VPATH=$(V_VPATH)
@ -9,9 +9,9 @@ C=.c
V_H=0
V_L=98
P_L=0
P_L=1
#define D_P_L 0
#define D_P_L 1
DISTRIB=mars_nwe
#if D_P_L
DISTRIBF=$(DISTRIB)-$(V_H).$(V_L).pl$(P_L)
@ -106,7 +106,7 @@ PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
nwqueue$(O)
nwqueue$(O) nameos2$(O)
OBJ4= $(OBJ1)
OBJ5= $(OBJ1)
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O)

271
nameos2.c Normal file
View File

@ -0,0 +1,271 @@
/* nameos2.c 08-Aug-96 : NameSpace OS2 Services, mars_nwe */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "net.h"
#include <dirent.h>
#include <utime.h>
#ifndef LINUX
#include <errno.h>
#endif
#include "nwvolume.h"
#include "connect.h"
#include "nwfile.h"
#include "unxfile.h"
#include "nameos2.h"
#if WITH_NAME_SPACE_CALLS
#define MAX_NAME_OS2_CACHE 0
#if MAX_NAME_OS2_CACHE
typedef struct {
uint8 *cache[MAX_NAME_OS2_CACHE];
} OS2BUF;
static void init_os2buf(NW_VOL *vol)
{
vol->os2buf = xcmalloc(sizeof(OS2BUF));
}
static int vgl_name(uint8 *s, uint8 *p)
{
int hit=0;
if (!s) return(0);
for (; *s && *p; s++,p++) {
if (*s == *p) {
if (*s == '/')
++hit;
} else if ((!isalpha(*p)) || (!isalpha(*s))
|| (*p | 0x20) != (*s | 0x20)) {
return(hit);
}
}
return((*s == *p) ? -1 : hit);
}
#endif
static int my_match(uint8 *s, uint8 *p)
{
int len=0;
for (; *s && *p; s++,p++) {
if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s))
|| (*p | 0x20) != (*s | 0x20)))
return(0);
++len;
}
return( ((!*s) && (*p=='/' || *p == '\0')) ? len : 0);
}
static int get_match(uint8 *unixname, uint8 *p)
{
DIR *d;
if (!p || !*p) return(1);
*p = '\0';
if (NULL != (d=opendir(unixname))) {
struct dirent *dirbuff;
XDPRINTF((10, 0, "opendir OK unixname='%s' p='%s'", unixname, p+1));
*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);
XDPRINTF((10, 0, "get match, match OK"));
closedir(d);
return(get_match(unixname, p+1+len));
}
}
}
closedir(d);
} else {
XDPRINTF((2, 0, "os2 get_match opendir failed unixname='%s'", unixname));
*p='/';
}
return(0);
}
#if MAX_NAME_OS2_CACHE
static int get_name(uint8 *s, uint8 *unixname, int hit, uint8 *p)
{
if (hit && s) {
for (; *s && *p; s++,p++) {
if (*s=='/') {
if (!--hit) break;
} else *p=*s;
}
} else
--p; /* to get last '/' */
return(get_match(unixname, p));
}
#endif
void mangle_os2_name(NW_VOL *vol, uint8 *unixname, uint8 *pp)
{
#if MAX_NAME_OS2_CACHE
int k = -1;
int besthit = -1;
int maxhits = 0;
OS2BUF *b;
if (!vol->os2buf) init_os2buf(vol);
b= (OS2BUF*)vol->os2buf;
while (++k < MAX_NAME_OS2_CACHE) {
int hits=vgl_name(b->cache[k], pp);
if (hits < 0) {
besthit=k;
break;
} else if (hits > maxhits) {
besthit=k;
maxhits =hits;
}
}
if (maxhits > -1) {
/* do not completely match */
if (get_name(maxhits ? b->cache[besthit] : NULL,
unixname, maxhits, pp)) {
int k=MAX_NAME_OS2_CACHE-1;
xfree(b->cache[k]);
while (k--) {
b->cache[k+1] = b->cache[k];
}
b->cache[0] = NULL;
new_str(b->cache[0], pp);
}
} else {
strcpy(pp, b->cache[besthit]);
if (besthit > 2) {
uint8 *sp=b->cache[besthit];
while (besthit--) {
b->cache[besthit+1] = b->cache[besthit];
}
b->cache[0] = sp;
}
}
#else
get_match(unixname, pp-1);
#endif
}
int fn_os2_match(uint8 *s, uint8 *p, int soptions)
/* OS/2 name matching routine */
{
int pc, sc;
uint state = 0;
int anf, ende;
int not = 0;
uint found = 0;
while ( (pc = *p++) != 0) {
if (!(soptions & VOL_OPTION_IGNCASE)) {
if (soptions & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */
if (*s >= 'A' && *s <= 'Z') return(0);
} else {
if (*s >= 'a' && *s <= 'z') return(0);
}
}
switch (state){
case 0 :
if (pc == 255) {
switch (pc=*p++) {
case 0xaa :
case '*' : pc=3000; break; /* star */
case 0xae :
case '.' : pc=1000; break; /* point */
case 0xbf :
case '?' : pc=2000; break; /* ? */
default : break;
}
} else if (pc == '\\') continue;
switch (pc) {
case '.' :
case 1000: if (*s && ('.' != *s++) ) return(0);
break;
case '?' :
case 2000: if (!*s) return(0);
++s;
break;
case '*' :
case 3000: if (!*p) return(1); /* last star */
while (*s) {
if (fn_os2_match(s, p, soptions) == 1) return(1);
else if (*s=='.' && !*(p+1)) return(0);
++s;
}
if (*p == '.') return(fn_os2_match(s, p, soptions));
return(0);
case '[' : if ( (*p == '!') || (*p == '^') ){
++p;
not = 1;
}
state = 1;
continue;
default : if (soptions & VOL_OPTION_IGNCASE) {
if ( pc != *s &&
( (!isalpha(pc))
|| (!isalpha(*s))
|| (pc | 0x20) != (*s | 0x20) ) )
return(0);
} else if (pc != *s) return(0);
++s;
break;
} /* switch */
break;
case 1 : /* Bereich von Zeichen */
sc = *s++;
found = not;
if (!sc) return(0);
do {
if (pc == '\\') pc = *(p++);
if (!pc) return(0);
anf = pc;
if (*p == '-' && *(p+1) != ']'){
ende = *(++p);
p++;
}
else ende = anf;
if (found == not) { /* only if not found */
if (anf == sc || (anf <= sc && sc <= ende))
found = !not;
}
} while ((pc = *(p++)) != ']');
if (! found ) return(0);
not = 0;
found = 0;
state = 0;
break;
default : break;
} /* switch */
} /* while */
if (*s=='.' && *(s+1)=='\0') return(1);
return ( (*s) ? 0 : 1);
}
#endif

14
nameos2.h Normal file
View File

@ -0,0 +1,14 @@
/*
* nameos2.h: 08-Aug-96
*
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*/
#ifndef _NAMEOS2_H_
#define _NAMEOS2_H_
#if WITH_NAME_SPACE_CALLS
extern void mangle_os2_name(NW_VOL *vol, uint8 *unixname, uint8 *pp);
extern int fn_os2_match(uint8 *s, uint8 *p, int soptions);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NAMSPACE_H_
#define _NAMSPACE_H_
#if WITH_NAME_SPACE_CALLS
#define NAME_DOS 0
@ -33,6 +35,23 @@ typedef struct {
uint8 pathes[1]; /* form len+name */
} NW_HPATH;
typedef struct {
uint8 attributes[4];
uint8 created_date[2];
uint8 created_time[2];
uint8 created_id[4];
uint8 modified_date[2];
uint8 modified_time[2];
uint8 modified_id[4];
uint8 archived_date[2];
uint8 archived_time[2];
uint8 archived_id[4];
uint8 last_access_date[2];
uint8 rightsgrantmask[2];
uint8 rightsrevokemask[2];
uint8 maxspace[4];
} DOS_MODIFY_INFO;
#define INFO_MSK_ENTRY_NAME 0x00000001
#define INFO_MSK_DATA_STREAM_SPACE 0x00000002
#define INFO_MSK_ATTRIBUTE_INFO 0x00000004
@ -67,7 +86,31 @@ typedef struct {
#define OPC_ACTION_REPLACE 0x04
/* Modify File or Subdirektory DOS Info infomask */
#define DOS_MSK_ATTRIBUTE 0x00000002
#define DOS_MSK_CREAT_DATE 0x00000004
#define DOS_MSK_CREAT_TIME 0x00000008
#define DOS_MSK_CREAT_ID 0x00000010
#define DOS_MSK_ARCHIVE_DATE 0x00000020
#define DOS_MSK_ARCHIVE_TIME 0x00000040
#define DOS_MSK_ARCHIVE_ID 0x00000080
#define DOS_MSK_MODIFY_DATE 0x00000100
#define DOS_MSK_MODIFY_TIME 0x00000200
#define DOS_MSK_MODIFY_ID 0x00000400
#define DOS_MSK_ACCESS_DATE 0x00000800
#define DOS_MSK_INHERIT_RIGHTS 0x00001000
#define DOS_MSK_MAX_SPACE 0x00002000
extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task);
extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task);
extern int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata);
#endif
#endif

5
net.h
View File

@ -19,6 +19,7 @@
#ifndef _M_NET_H_
#define _M_NET_H_
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
@ -214,6 +215,10 @@ extern int errno;
# define MAX_DIR_BASE_ENTRIES 50
#endif
#if MAX_DIR_BASE_ENTRIES < 10
# define MAX_DIR_BASE_ENTRIES 10
#endif
#ifndef MAX_NW_ROUTES
# define MAX_NW_ROUTES 50
#endif

View File

@ -1,5 +1,5 @@
/* nwbind.c */
#define REVISION_DATE "12-Jul-96"
#define REVISION_DATE "14-Aug-96"
/* NCP Bindery SUB-SERVER */
/* authentification and some message handling */
@ -1147,6 +1147,18 @@ static void handle_fxx(int gelen, int func)
completition=0xd5; /* no Queue Job */
}break;
case 0x81 : { /* Get Queue Job List */
NETOBJ obj;
struct XDATA {
uint8 total_jobs[4];
uint8 reply_numbers[4];
uint8 job_list[4]; /* this is repeated */
} *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata);
XDPRINTF((2, 0, "TODO:GET QUEUE JOB List of Q=0x%lx", obj.id));
memset(xdata, 0, sizeof(struct XDATA));
}break;
case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */
XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV"));
/* !!!!!! TODO completition=0xc6 (no rights) */

115
nwconn.c
View File

@ -683,6 +683,20 @@ static int handle_ncp_serv(void)
completition = 0xfb; /* TODO: !!! */
} else if (*p == 0x2f){ /* ?????? */
completition = 0xfb; /* TODO: !!! */
#if WITH_NAME_SPACE_CALLS
} else if (*p == 0x30){
/* Get Name Space Directory Entry */
int volume = (int) *(p+1);
uint32 basehandle = GET_32(p+2);
int namespace = (int) *(p+6);
int result=get_namespace_dir_entry(
volume, basehandle, namespace,
responsedata);
if (result > -1) {
data_len = result;
} else completition = (uint8) -result;
#endif
} else completition = 0xfb; /* unkwown request */
}
break;
@ -696,7 +710,7 @@ static int handle_ncp_serv(void)
#if FUNC_17_02_IS_DEBUG
case 0x02 : {
/* I hope this is call isn't used */
/* I hope this call isn't used */
/* now missused as a debug switch :) */
struct XDATA {
uint8 nw_debug; /* old level */
@ -730,7 +744,7 @@ static int handle_ncp_serv(void)
uint8 data[2]; /* Name */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 sequence[2]; /* next sequence */
/* NW_FILE_INFO f; */
uint8 f[sizeof(NW_FILE_INFO)];
@ -738,11 +752,11 @@ static int handle_ncp_serv(void)
uint8 archive_date[2];
uint8 archive_time[2];
uint8 reserved[56];
} *xdata = (struct OUTPUT*)responsedata;
} *xdata = (struct XDATA*)responsedata;
int len = input->len;
int searchsequence;
NW_FILE_INFO f;
memset(xdata, 0, sizeof(struct OUTPUT));
memset(xdata, 0, sizeof(struct XDATA));
searchsequence = nw_search( (uint8*) &f,
(int)input->dir_handle,
(int) GET_BE16(input->sequence),
@ -752,7 +766,7 @@ static int handle_ncp_serv(void)
memcpy(xdata->f, &f, sizeof(NW_FILE_INFO));
U16_TO_BE16((uint16) searchsequence, xdata->sequence);
U32_TO_BE32(1L, xdata->owner_id); /* Supervisor */
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
} else completition = (uint8) (- searchsequence);
}
break;
@ -844,13 +858,12 @@ static int handle_ncp_serv(void)
break;
case 0x21 : { /* Negotiate Buffer Size, Packetsize */
int wantsize = GET_BE16((uint8*)ncprequest);
int wantsize = GET_BE16((uint8*)requestdata);
uint8 *getsize=responsedata;
#if IPX_DATA_GR_546
wantsize = min(0x400, wantsize);
#else
#if !IPX_DATA_GR_546
wantsize = min(0x200, wantsize);
#else
wantsize = min(0x400, wantsize);
#endif
U16_TO_BE16(wantsize, getsize);
data_len = 2;
@ -923,7 +936,7 @@ static int handle_ncp_serv(void)
} *input = (struct INPUT *) ncprequest;
int len=input->len ; /* FN Length */
struct OUTPUT {
struct XDATA {
uint8 searchsequence[2]; /* same as request sequence */
uint8 dir_id[2]; /* Direktory ID */
/* is correct !! */
@ -931,7 +944,7 @@ static int handle_ncp_serv(void)
NW_DIR_INFO d;
NW_FILE_INFO f;
} u;
} *xdata = (struct OUTPUT*)responsedata;
} *xdata = (struct XDATA*)responsedata;
int searchsequence = nw_dir_search(
(uint8*) &(xdata->u),
@ -942,7 +955,7 @@ static int handle_ncp_serv(void)
if (searchsequence > -1) {
U16_TO_BE16((uint16) searchsequence, xdata->searchsequence);
memcpy(xdata->dir_id, input->dir_id, 2);
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
} else completition = (uint8) (- searchsequence);
}
break;
@ -957,14 +970,14 @@ static int handle_ncp_serv(void)
uint8 len;
uint8 data[2]; /* Name */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 sequenz[2]; /* answer sequence */
uint8 reserved[2]; /* z.B 0x0 0x0 */
union {
NW_DIR_INFO d;
NW_FILE_INFO f;
} u;
} *xdata = (struct OUTPUT*)responsedata;
} *xdata = (struct XDATA*)responsedata;
int len = input->len;
uint8 my_sequenz[2];
int searchsequence;
@ -976,7 +989,7 @@ static int handle_ncp_serv(void)
input->data, len);
if (searchsequence > -1) {
U16_TO_BE16((uint16) searchsequence, xdata->sequenz);
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
} else completition = (uint8) (- searchsequence);
}
break;
@ -990,12 +1003,12 @@ static int handle_ncp_serv(void)
uint8 len; /* namelaenge */
uint8 data[2]; /* Name */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 ext_fhandle[2]; /* all zero */
uint8 fhandle[4]; /* Dateihandle */
uint8 reserve2[2]; /* z.B 0x0 0x0 */
NW_FILE_INFO fileinfo;
} *xdata= (struct OUTPUT*)responsedata;
} *xdata= (struct XDATA*)responsedata;
int fhandle=nw_creat_open_file((int)input->dirhandle,
input->data, input->len,
&(xdata->fileinfo),
@ -1006,7 +1019,7 @@ static int handle_ncp_serv(void)
U32_TO_BE32(fhandle, xdata->fhandle);
U16_TO_BE16(0, xdata->ext_fhandle);
U16_TO_BE16(0, xdata->reserve2);
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
} else completition = (uint8) (-fhandle);
}
break;
@ -1038,12 +1051,12 @@ static int handle_ncp_serv(void)
uint8 len;
uint8 data[1]; /* Name */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 extfhandle[2];
uint8 fhandle[4]; /* Filehandle */
uint8 reserved[2]; /* rese. by NOVELL */
NW_FILE_INFO fileinfo;
} *xdata= (struct OUTPUT*)responsedata;
} *xdata= (struct XDATA*)responsedata;
int fhandle=nw_creat_open_file(
(int)input->dirhandle,
input->data,
@ -1053,7 +1066,7 @@ static int handle_ncp_serv(void)
0,
(function==0x43) ? 1 : 2);
if (fhandle > -1){
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
U32_TO_BE32(fhandle, xdata->fhandle);
U16_TO_BE16(0, xdata->extfhandle);
U16_TO_BE16(0, xdata->reserved);
@ -1134,13 +1147,13 @@ static int handle_ncp_serv(void)
uint8 ext_filehandle[2]; /* all zero */
uint8 fhandle[4]; /* Dateihandle */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 size[4]; /* Position ??? */
} *xdata=(struct OUTPUT*)responsedata;
} *xdata=(struct XDATA*)responsedata;
int fhandle = GET_BE32(input->fhandle);
int size = nw_seek_datei(fhandle, 0);
if (size > -1) {
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
U32_TO_BE32(size, xdata->size);
}
else completition = (uint8) -size;
@ -1157,10 +1170,10 @@ static int handle_ncp_serv(void)
uint8 offset[4];
uint8 max_size[2]; /* byte to readd */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 size[2]; /* read byzes */
uint8 data[1072]; /* max data */
} *xdata=(struct OUTPUT*)responsedata;
} *xdata=(struct XDATA*)responsedata;
int fhandle = GET_BE32(input->fhandle);
int max_size = GET_BE16(input->max_size);
off_t offset = GET_BE32(input->offset);
@ -1226,11 +1239,11 @@ static int handle_ncp_serv(void)
input_size);
if (size < 0) completition = (uint8) -size;
else {
struct OUTPUT {
struct XDATA {
uint8 zsize[4]; /* real transfered Bytes */
} *xdata= (struct OUTPUT*)responsedata;
} *xdata= (struct XDATA*)responsedata;
U32_TO_BE32(size, xdata->zsize);
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
}
}
break;
@ -1266,12 +1279,12 @@ static int handle_ncp_serv(void)
uint8 len; /* namelaenge */
uint8 data[2]; /* Name */
} *input = (struct INPUT *)ncprequest;
struct OUTPUT {
struct XDATA {
uint8 ext_fhandle[2]; /* all zero */
uint8 fhandle[4]; /* Dateihandle */
uint8 reserve2[2]; /* z.B 0x0 0x0 */
NW_FILE_INFO fileinfo;
} *xdata= (struct OUTPUT*)responsedata;
} *xdata= (struct XDATA*)responsedata;
int fhandle=nw_creat_open_file((int)input->dirhandle,
input->data, input->len,
&(xdata->fileinfo),
@ -1283,7 +1296,7 @@ static int handle_ncp_serv(void)
U16_TO_BE16(0, xdata->ext_fhandle);
U16_TO_BE16(0, xdata->reserve2);
data_len = sizeof(struct OUTPUT);
data_len = sizeof(struct XDATA);
#ifdef TEST_FNAME
input->data[input->len] = '\0';
if (strstr(input->data, TEST_FNAME)){
@ -1326,28 +1339,46 @@ static int handle_ncp_serv(void)
#endif
#ifdef _MAR_TESTS_
#if 0
case 0x61 : { /* Negotiate Buffer Size, Packetsize new ? */
/* > 3.11 */
int wantsize = GET_BE16((uint8*)ncprequest);
int wantsize = GET_BE16((uint8*)requestdata);
int flags = (int) *(requestdata+2);
/* wantsize is here normally 1500 */
/* 1 byte unknown ( zero ) */
struct OUTPUT {
struct XDATA {
uint8 getsize[2];
uint8 socket[2]; /* socket for echo ?? */
uint8 unknown; /* zero */
} *xdata= (struct OUTPUT*)responsedata;
uint8 socket[2]; /* echo socket */
uint8 flags; /* zero */
} *xdata= (struct XDATA*)responsedata;
memset(xdata, 0, sizeof(*xdata));
wantsize = min(1500, wantsize);
U16_TO_BE16(wantsize, xdata->getsize);
U16_TO_BE16(sock_echo, xdata->socket);
data_len = sizeof(*xdata);
XDPRINTF((5,0, "Negotiate Buffer (new) =0x%04x,(%d)",
(int) wantsize, (int) wantsize));
XDPRINTF((5,0, "Negotiate Buffer (new) =0x%04x,(%d), flags=0x%x",
(int) wantsize, (int) wantsize, flags));
}
break;
#endif
#if 0
case 0x65 : /* Packet Burst Connection Request */
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 conn_id[4]; /* ?? */
uint8 max_packet_size[4]; /* HI-LOW */
uint8 target_socket[2];
uint8 max_sent_size[4]; /* HI-LOW */
uint8 max_recv_size[4]; /* HI-LOW */
} *input = (struct INPUT *)ncprequest;
struct XDATA {
uint8 result;
uint8 target_id[4];
uint8 max_packet_size[4];
} *xdata= (struct XDATA*) responsedata;
break;
#endif
#if 0
case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */
#endif

View File

@ -1291,7 +1291,7 @@ static void add_pr_queue(uint32 q_id,
"Q_DIRECTORY", P_FL_ITEM, 0x33,
q_directory, strlen(q_directory));
/* this is a own property to handler the print job !!! */
/* this is an own property to handle the print job !!! */
nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 ,
"Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33,
q_command, strlen(q_command));
@ -1300,7 +1300,6 @@ static void add_pr_queue(uint32 q_id,
nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_USERS", P_FL_SET, 0x31,
(char*)buff, 4);
#if 0
nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 ,
"Q_SERVERS", P_FL_SET, 0x31,

View File

@ -348,16 +348,12 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
size = fread(data, 1, size, fh->f->fildes[1]);
else {
size = read(fh->fd, data, size);
if (size < 0) {
int k=5;
while (size < 0 && --k /* && errno == EAGAIN */)
size = read(fh->fd, data, size);
}
}
} else {
#if USE_MMAP
if (fh->p_mmap) {
@ -430,11 +426,7 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->fd > -1) {
if (fh->fh_flags & FH_IS_READONLY) return(-0x94);
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
if (size) {
if (fh->fh_flags & FH_IS_PIPE_COMMAND)
return(fwrite(data, 1, size, fh->f->fildes[0]));
return(write(fh->fd, data, size));
} return(0);
return(size ? write(fh->fd, data, size) : 0);
} else {
if (fh->offd != (long)offset)
fh->offd = lseek(fh->fd, offset, SEEK_SET);

View File

@ -1,4 +1,4 @@
/* nwconn.c 16-Jul-96 */
/* nwconn.c 10-Aug-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -18,8 +18,10 @@
#include "net.h"
#include <dirent.h>
#include "connect.h"
#include "nwvolume.h"
#include "nwfile.h"
#include "connect.h"
#include "nwqueue.h"
static char **build_argv(char *buf, int bufsize, char *command)
@ -135,6 +137,7 @@ static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp)
int x_ = (j) ? 1 : 0;
close(piped[j][x_]);
piped [j][x_] = -1;
fp->fildes [j] = fdopen(piped[j][x], ( (j) ? "r" : "w") );
if (NULL == fp->fildes[j]){
err_close_pipe(fp, lpid, j+1, piped);
@ -150,8 +153,6 @@ int ext_pclose(FILE_PIPE *fp)
void (*intsave) (int) = signal(SIGINT, SIG_IGN);
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
int j = 3;
while (j--) if (fp->fildes[j]) fclose(fp->fildes[j]);
if (fp->command_pid != waitpid(fp->command_pid, &status, 0)) {
@ -388,7 +389,10 @@ int nw_close_file_queue(uint8 *queue_id,
int k;
is_ok++;
while ((k = fread(buff, 1, sizeof(buff), f)) > 0) {
/*
if (1 != fwrite(buff, k, 1, fp->fildes[0])) {
*/
if (k != write(fileno(fp->fildes[0]), buff, k)) {
XDPRINTF((1,0,"Cannot write to pipe `%s`", printcommand));
is_ok=0;
}

View File

@ -1205,6 +1205,10 @@ int main(int argc, char **argv)
{
int j = 0;
int init_mode=0;
if (seteuid(0) < 0 || setuid(0) < 0) {
fprintf(stderr, "You must have root permission !\n");
exit(1);
}
tzset();
while (++j < argc) {
char *a=argv[j];
@ -1252,7 +1256,6 @@ int main(int argc, char **argv)
time(&broadtime);
set_sigs();
creat_pidfile();
polls[NEEDED_SOCKETS].fd = fd_nwbind_in;

View File

@ -1,4 +1,4 @@
/* nwvolume.c 14-Jul-96 */
/* nwvolume.c 08-Aug-96 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -64,6 +64,7 @@ void nw_init_volumes(FILE *f)
if (founds > 1) {
NW_VOL *vol=&(nw_volumes[used_nw_volumes]);
vol->options = VOL_NAMESPACE_DOS;
upstr(sysname);
new_str(vol->sysname, sysname);
if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') {
vol->options |= VOL_OPTION_IS_HOME;
@ -78,6 +79,10 @@ void nw_init_volumes(FILE *f)
if (founds > 2) {
for (p=optionstr; *p; p++) {
switch (*p) {
case 'i' : vol->options
|= VOL_OPTION_IGNCASE;
break;
case 'k' : vol->options
|= VOL_OPTION_DOWNSHIFT;
break;
@ -319,15 +324,16 @@ int get_volume_options(int volnr, int mode)
return(result);
}
int get_volume_inode(int volnr)
int get_volume_inode(int volnr, struct stat *stb)
/* returns inode if OK, else errocode < 0 */
{
int result = -0x98; /* Volume not exist */;
if (volnr > -1 && volnr < used_nw_volumes) {
struct stat statb;
result = stat(nw_volumes[volnr].unixname, &statb);
if (!stb) stb=&statb;
result = stat(nw_volumes[volnr].unixname, stb);
if (result == -1) result=-0x98;
else result=statb.st_ino;
else result=stb->st_ino;
}
XDPRINTF((5,0,"get_volume_inode of VOLNR:%d, result=0x%x", volnr, result));
return(result);

View File

@ -1,4 +1,4 @@
/* nwvolume.h 14-Jul-96 */
/* nwvolume.h 27-Jul-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -33,22 +33,25 @@ typedef struct {
typedef struct {
uint8 *sysname; /* VOL_NAME */
uint8 *unixname; /* UNIX-DIR */
uint8 *unixname; /* UNIX-DIR with ending '/' */
int unixnamlen; /* len of unixname */
DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS];
int max_maps_count; /* may be less than MAX_DEV_NAMESPACE_MAPS */
int maps_count; /* count of dev_namespace_maps */
uint32 high_inode; /* hight inode to can handle correct */
int options; /* see defines below */
uint8 *os2buf; /* special stuff for os2 namspace */
} NW_VOL;
/* vol options */
#define VOL_OPTION_DOWNSHIFT 0x0001 /* All downshift */
#define VOL_OPTION_DOWNSHIFT 0x0001 /* downshift */
#define VOL_OPTION_IS_PIPE 0x0002 /* Volume contains pipes */
#define VOL_OPTION_REMOUNT 0x0004 /* Volume can be remounted (cdroms) */
#define VOL_OPTION_IS_HOME 0x0008 /* Volume is USERS HOME */
#define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */
#define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */
#define VOL_OPTION_IGNCASE 0x0040 /* Do ignore up/downshift */
/* namespaces */
#define VOL_NAMESPACE_DOS 0x1000
#define VOL_NAMESPACE_OS2 0x2000
@ -73,7 +76,7 @@ extern int nw_get_volume_number(uint8 *volname, int namelen);
extern int nw_get_volume_name(int volnr, uint8 *volname);
extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu);
extern int get_volume_options(int volnr, int mode);
extern int get_volume_inode(int volnr);
extern int get_volume_inode(int volnr, struct stat *stb);
extern uint32 nw_vol_inode_to_handle(int volume, ino_t inode,
DEV_NAMESPACE_MAP *dnm);

42
tools.c
View File

@ -1,4 +1,4 @@
/* tools.c 13-May-96 */
/* tools.c 07-Aug-96 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -26,7 +26,7 @@ extern char *_sys_errlist[];
int nw_debug=0;
FILE *logfile=stdout;
FILE *logfile=stderr;
static int in_module=0; /* in which process i am ? */
static int connection=0; /* which connection (nwconn) */
@ -279,7 +279,7 @@ static char *get_pidfilefn(char *buf)
return(get_div_pathes(buf, (char*)downstr((uint8*)lbuf), 2, ".pid"));
}
void creat_pidfile(void)
static void creat_pidfile(void)
{
char buf[300];
char *pidfn=get_pidfilefn(buf);
@ -288,7 +288,8 @@ void creat_pidfile(void)
fprintf(f, "%d\n", getpid());
fclose(f);
} else {
XDPRINTF((1, 0, "Cannot creat pidfile=%s", pidfn));
errorp(1, "INIT", "Cannot creat pidfile=%s", pidfn);
exit(1);
}
}
@ -301,6 +302,7 @@ void init_tools(int module, int options)
int dodaemon=0;
int new_log=0;
in_module = module;
my_pid = getpid();
connection = (NWCONN == module) ? options : 0;
if (NWSERV == module || NWROUTED == module) {
int kill_pid=-1;
@ -351,18 +353,19 @@ void init_tools(int module, int options)
if (NWSERV == module || NWROUTED == module) { /* now make daemon */
int fd=fork();
if (fd) exit((fd > 0) ? 0 : 1);
my_pid=getpid();
}
if (NULL == (logfile = fopen(logfilename,
(new_log && (NWSERV == module || NWROUTED == module)) ? "w" : "a"))) {
char sxx[100];
sprintf(sxx, "\n\nOpen logfile `%s`", logfilename);
perror(sxx);
logfile = stdout;
fprintf(stderr, "\n!! ABORTED !!\n");
logfile = stderr;
errorp(1, "INIT", "Cannot open logfile='%s'",logfilename);
exit(1);
}
if (NWSERV == module || NWROUTED == module) setsid();
if (NWSERV == module || NWROUTED == module) {
creat_pidfile();
setsid();
}
} else logfile=stdout;
if ( NWCONN != module || nw_debug > 1 ) {
XDPRINTF((1, 0, "Starting Version: %d.%02dpl%d",
_VERS_H_, _VERS_L_, _VERS_P_ ));
@ -371,7 +374,6 @@ void init_tools(int module, int options)
if (nw_debug < 8)
sigsegv_func = signal(SIGSEGV, sig_segv);
#endif
my_pid = getpid();
}
void exit_tools(void)
@ -380,20 +382,15 @@ void exit_tools(void)
char buf[300];
unlink(get_pidfilefn(buf));
}
if (logfile != stdout) {
if (logfile != NULL) fclose(logfile);
logfile=stdout;
}
}
uint8 down_char(uint8 ch)
{
if (ch > 64 && ch < 91) return(ch + 32);
switch(ch){
case 142: ch = 132; break;
case 153: ch = 148; break;
case 154: ch = 129; break;
default :break;
case 142: return(132);
case 153: return(148);
case 154: return(129);
}
return(ch);
}
@ -402,10 +399,9 @@ uint8 up_char(uint8 ch)
{
if (ch > 96 && ch < 123) return(ch - 32);
switch(ch) {
case 132: ch = 142; break;
case 148: ch = 153; break;
case 129: ch = 154; break;
default : break;
case 132: return(142);
case 148: return(153);
case 129: return(154);
}
return(ch);
}

View File

@ -50,7 +50,6 @@ extern char *get_div_pathes(char *buff, char *name, int what, char *p, ... );
extern int get_ini_int(int what);
extern void get_ini_debug(int what);
extern void creat_pidfile(void);
extern void init_tools(int module, int options);
extern void exit_tools(void);