mars_nwe-0.98.pl11

This commit is contained in:
Mario Fetka 2011-11-13 00:38:58 +01:00
parent 3b6ddaabdf
commit 70cf9be941
50 changed files with 2239 additions and 1034 deletions

253
connect.c
View File

@ -1,4 +1,4 @@
/* connect.c 07-Nov-96 */
/* connect.c 11-Jun-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,13 @@
/* #define TEST_FNAME "PRINT.000"
*/
int use_mmap=USE_MMAP;
int tells_server_version=1;
int max_burst_send_size=0x2000;
int max_burst_recv_size=0x2000;
#ifdef TEST_FNAME
static int test_handle=-1;
#endif
@ -33,10 +40,23 @@ static int default_gid=-1;
static int default_umode_dir=0775;
static int default_umode_file=0664;
#include "nwfname.h"
#include "nwvolume.h"
#include "nwfile.h"
#include "connect.h"
typedef struct {
ino_t inode; /* Unix Inode dieses Verzeichnisses */
time_t timestamp; /* Zeitmarke */
uint8 *path; /* path ab Volume */
uint8 volume; /* Welches Volume */
uint8 is_temp; /* 0:perm. 1:temp 2: spez. temp */
uint8 drive; /* driveletter */
uint8 task; /* actual task */
} NW_DIR;
NW_DIR dirs[MAX_NW_DIRS];
int used_dirs=0;
int act_uid=-1;
@ -52,6 +72,19 @@ static int connect_is_init = 0;
#define MAX_DIRHANDLES 80
typedef struct {
DIR *f;
char unixname[256]; /* kompletter unixname */
ino_t inode; /* Unix Inode */
time_t timestamp; /* f<>r letzte Allocierung */
char *kpath; /* Ein Zeichen nach unixname */
int vol_options; /* searchoptions */
int volume; /* Volume Number */
int sequence; /* Search sequence */
off_t dirpos; /* Current pos in unix dir */
} DIR_HANDLE;
static DIR_HANDLE dir_handles[MAX_DIRHANDLES];
static int anz_dirhandles=0;
@ -86,6 +119,7 @@ static char *build_unix_name(NW_PATH *nwpath, int modus)
*p = '\0';
}
}
dos2unixcharset(unixname);
return(unixname);
}
@ -103,6 +137,10 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
int nhandle = 0;
for (rethandle=0; rethandle < anz_dirhandles; rethandle++){
dh=&(dir_handles[rethandle]);
if (dh->f) { /* only the actual dir-handle should remain open */
closedir(dh->f);
dh->f=NULL;
}
if (!dh->inode) {
if (!nhandle)
nhandle = rethandle+1;
@ -359,8 +397,7 @@ static int x_str_match(uint8 *s, uint8 *p, int soptions)
default : /* 'normal' chars */
if (soptions & VOL_OPTION_IGNCASE) {
if (*s != pc && ((!isalpha(pc)) || (!isalpha(*s))
|| (pc | 0x20) != (*s | 0x20)))
if (!dfn_imatch(*s, pc))
return(0);
} else if (pc != *s) return(0);
s++;
@ -468,9 +505,7 @@ 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));
@ -483,18 +518,21 @@ static int func_search_entry(NW_PATH *nwpath, int attrib,
okflag = 0;
if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name);
uint8 dname[256];
xstrcpy(dname, name);
unix2doscharset(dname);
okflag = (name[0] != '.' &&
( (entry[0] == '*' && entry[1] == '\0')
|| (!strcmp((char*)name, (char*)entry))
|| fn_dos_match(name, entry, soptions)));
|| (!strcmp((char*)dname, (char*)entry))
|| fn_dos_match(dname, entry, soptions)));
if (okflag) {
*kpath = '\0';
strcpy(kpath, (char*)name);
if (!stat(xkpath, &(fs->statb))) {
if (!s_stat(xkpath, &(fs->statb), NULL)) {
okflag = ( ( ( (fs->statb.st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
strcpy((char*)nwpath->fn, (char*)name);
strcpy((char*)nwpath->fn, (char*)dname);
XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode));
result = (*fs_func)(nwpath, fs);
if (result < 0) break;
@ -528,9 +566,6 @@ 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:",
@ -553,18 +588,21 @@ static int get_dir_entry(NW_PATH *nwpath,
(*sequence)++;
if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name);
uint8 dname[256];
xstrcpy(dname, name);
unix2doscharset(dname);
okflag = (name[0] != '.' &&
( (entry[0] == '*' && entry[1] == '\0')
|| (!strcmp((char*)name, (char*)entry))
|| fn_dos_match(name, entry, soptions)));
|| (!strcmp((char*)dname, (char*)entry))
|| fn_dos_match(dname, entry, soptions)));
if (okflag) {
*kpath = '\0';
strcpy(kpath, (char*)name);
if (!stat(xkpath, statb)) {
if (!s_stat(xkpath, statb, NULL)) {
okflag = ( ( ( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
strcpy((char*)nwpath->fn, (char*)name);
strcpy((char*)nwpath->fn, (char*)dname);
XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode));
break; /* ready */
}
@ -610,12 +648,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) {
if (*sequence < dh->sequence || ((long)dh->dirpos) < 0L) {
dh->dirpos = (off_t)0;
dh->sequence = 0;
}
@ -640,21 +675,24 @@ static int get_dh_entry(DIR_HANDLE *dh,
dh->sequence++;
if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name);
uint8 dname[256];
xstrcpy(dname, name);
unix2doscharset(dname);
okflag = (name[0] != '.' && (
(!strcmp((char*)name, (char*)entry)) ||
(!strcmp((char*)dname, (char*)entry)) ||
(entry[0] == '*' && entry[1] == '\0')
|| fn_dos_match(name, entry, dh->vol_options)));
|| fn_dos_match(dname, entry, dh->vol_options)));
if (okflag) {
strcpy(dh->kpath, (char*)name);
XDPRINTF((5,0,"get_dh_entry Name=%s unixname=%s",
name, dh->unixname));
if (!stat(dh->unixname, statb)) {
if (!s_stat(dh->unixname, statb, NULL)) {
okflag = ( (( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
strcpy((char*)search, (char*)name);
strcpy((char*)search, (char*)dname);
break; /* ready */
}
} else okflag = 0;
@ -684,11 +722,6 @@ 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 */
}
#endif
else if (*data == 0xaa|| *data == '*' ) {
*p1++ = '*';
(*has_wild)++;
@ -702,7 +735,7 @@ static void conn_build_path_fn( uint8 *vol,
int len = (int) (p1 - path);
memcpy(vol, path, len);
vol[len] = '\0';
upstr(vol);
up_fn(vol);
p1 = path;
} else *p1++ = *data;
data++;
@ -747,11 +780,11 @@ static int build_path( NW_PATH *path,
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);
down_fn(path->path);
down_fn(path->fn);
} else {
upstr(path->path);
upstr(path->fn);
up_fn(path->path);
up_fn(path->fn);
}
break;
}
@ -777,7 +810,7 @@ static int nw_path_ok(NW_PATH *nwpath)
char pp[10];
while (*p=='/') ++p;
strmaxcpy(pp, p, 6);
upstr(pp);
up_fn(pp);
p=pp+5;
if (memcmp(pp, "LOGIN", 5) || (*p!='\0' && *p!='/') )
result=-0x9c;
@ -792,7 +825,7 @@ static int nw_path_ok(NW_PATH *nwpath)
}
d++;
} /* while */
if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff)
if (!s_stat(build_unix_name(nwpath, 1 | 2 ), &stbuff, NULL)
&& S_ISDIR(stbuff.st_mode))
return(stbuff.st_ino);
result = -0x9c; /* wrong path */
@ -846,13 +879,13 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
if (w == '.') state = 10;
else if (w == '/') state = 30;
else state++;
} else if (state == 9) completition= -0x9c; /* something wrong */
else if (state < 14){
if (state == 9) completition= -0x9c; /* something wrong */
} else if (state < 14){
if (w == '.') return(-0x9c);
else if (w == '/') state = 30;
else state++;
} else if (state == 14) completition= -0x9c; /* something wrong */
else if (state == 20){
if (state == 14) completition= -0x9c; /* something wrong */
} else if (state == 20){
if (ppp > nwpath->path)
ppp=nwpath->path;
if (w == '/') state = 30;
@ -893,11 +926,11 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
if (nwpath->volume > -1 && nwpath->volume < used_nw_volumes){
NW_VOL *v = &nw_volumes[nwpath->volume];
if (v->options & VOL_OPTION_DOWNSHIFT) {
downstr(ppp);
downstr(nwpath->fn);
down_fn(ppp);
down_fn(nwpath->fn);
} else {
upstr(ppp);
upstr(nwpath->fn);
up_fn(ppp);
up_fn(nwpath->fn);
}
if (v->options & VOL_OPTION_IGNCASE) {
uint8 unixname[1024]; /* should be enough */
@ -909,9 +942,11 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */
strcpy(pp, nwpath->path);
if (fnlen)
strcpy(pp+pathlen, nwpath->fn);
dos2unixcharset(pp);
pp += offset;
pathlen -= offset;
mangle_dos_name(v, unixname, pp);
unix2doscharset(pp);
XDPRINTF((5, 0, "Mangled DOS/unixname=%s", unixname));
memcpy(ppp, pp, pathlen);
if (fnlen)
@ -998,7 +1033,7 @@ time_t nw_2_un_time(uint8 *d, uint8 *t)
int day = xdate & 0x1f;
int hour = xtime >> 11;
int minu = (xtime >> 5) & 0x3f;
int sec = xtime & 0x1f;
int sec = (xtime & 0x1f) << 1; /* Tnx to Csoma Csaba */
struct tm s_tm;
s_tm.tm_year = year;
s_tm.tm_mon = month-1;
@ -1006,6 +1041,7 @@ time_t nw_2_un_time(uint8 *d, uint8 *t)
s_tm.tm_hour = hour;
s_tm.tm_min = minu;
s_tm.tm_sec = sec;
s_tm.tm_isdst = -1;
return(mktime(&s_tm));
}
@ -1105,9 +1141,9 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb,
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);
up_fn(f->name);
if (voloptions & VOL_OPTION_IS_PIPE)
f->attrib = 0;
f->attrib = FILE_ATTR_SHARE;
else
f->attrib = (uint8) un_nw_attrib(stb, 0, 0);
XDPRINTF((5,0, "get_file_attrib = 0x%x of ,%s, uid=%d, gid=%d",
@ -1128,7 +1164,7 @@ 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);
up_fn(d->name);
d->attrib = (uint8) un_nw_attrib(stb, 0, 0);
#if 0 /* changed: 02-Nov-96 */
d->ext_attrib = 0xff; /* effektive rights ?? */
@ -1171,27 +1207,32 @@ int nw_delete_datei(int dir_handle, uint8 *data, int len)
static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs)
{
char unname[256];
char unname[256];
int result=0;
NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf;
int voloption;
strcpy(unname, build_unix_name(nwpath, 0));
XDPRINTF((5,0,"set_file_info unname:%s:", unname));
if ((voloption = get_volume_options(nwpath->volume, 1)) & VOL_OPTION_IS_PIPE)
return(0); /* don't change 'pipe commands' */
else if (voloption & VOL_OPTION_READONLY)
return(-0x8c); /* no modify rights */
else {
if ((voloption = get_volume_options(nwpath->volume, 1)) & VOL_OPTION_IS_PIPE){
;; /* don't change 'pipe commands' */
} else if (voloption & VOL_OPTION_READONLY) {
result=(-0x8c); /* no modify rights */
} else {
struct utimbuf ut;
struct stat statb;
int result=0;
#if PERSISTENT_SYMLINKS
S_STATB stb;
#endif
ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time);
if ( 0 == (result=stat(unname, &statb)) &&
0 == (result=utime(unname, &ut))){
result = chmod(unname, un_nw_attrib(&statb, (int)f->attrib, 1));
if ( 0 == (result=s_stat(unname, &statb, &stb)) &&
0 == (result=s_utime(unname, &ut, &stb))){
result = s_chmod(unname,
un_nw_attrib(&statb, (int)f->attrib, 1), &stb);
}
return( (result != 0) ? -0x8c : 0); /* no modify rights */
if (result)
result= (-0x8c); /* no modify rights */
}
return(-0x85); /* NO Privileges */
XDPRINTF((5,0,"set_file_info result=0x%x, unname:%s:", unname, -result));
return(result);
}
int nw_set_file_information(int dir_handle, uint8 *data, int len,
@ -1218,6 +1259,9 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len,
struct stat stbuff;
int completition=-0x9c;
NW_PATH nwpath;
#if PERSISTENT_SYMLINKS
S_STATB stb;
#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);
@ -1225,10 +1269,12 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len,
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 2));
XDPRINTF((5,0,"set file attrib 0x%x, unname:%s:", access, unname));
if (!stat(unname, &stbuff)){
int result = chmod(unname, un_nw_attrib(&stbuff, access, 1));
if (!s_stat(unname, &stbuff, &stb)){
int result = s_chmod(unname, un_nw_attrib(&stbuff, access, 1), &stb);
return( (result != 0) ? -0x8c : 0); /* no modify rights */
}
return(-0x9c); /* wrong path */
}
@ -1348,9 +1394,9 @@ int mv_dir(int dir_handle, uint8 *q, int qlen,
(optz & VOL_OPTION_READONLY)) completition = -0x8b;
/* patch from Sven Norinder <snorinder@sgens.ericsson.se> :09-Nov-96 */
else if (optz & VOL_OPTION_DOWNSHIFT)
downstr(zielpath.fn);
down_fn(zielpath.fn);
else
upstr(zielpath.fn);
up_fn(zielpath.fn);
}
if (completition > -1){
int result;
@ -1460,7 +1506,9 @@ int nw_init_connect(void)
connect_is_init++;
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
if (what == 8) { /* entry8_flags */
if (what == 6) { /* version */
tells_server_version = atoi(buff);
} else if (what == 8) { /* entry8_flags */
entry8_flags = hextoi((char*)buff);
} else if (what == 9) { /* GID */
int umode_dir, umode_file;
@ -1472,6 +1520,18 @@ int nw_init_connect(void)
default_gid = atoi((char*)buff);
} else if (what == 11) { /* UID */
default_uid = atoi((char*)buff);
} else if (what == 30) { /* Burstmodus */
int recvsize, sendsize;
int i= sscanf((char*)buff, "%i %i", &recvsize, &sendsize);
if (i>0){
max_burst_recv_size=recvsize;
if (i>1)
max_burst_send_size=sendsize;
}
} else if (50 == what) {
init_nwfname(buff);
} else if (68 == what) { /* USE_MMAP */
use_mmap=atoi(buff);
} else if (what == 103) { /* Debug */
get_debug_level(buff);
}
@ -1484,7 +1544,7 @@ int nw_init_connect(void)
return(-1);
}
if (get_volume_options(0, 1) & VOL_OPTION_DOWNSHIFT)
downstr(nwlogin.path);
down_fn(nwlogin.path);
if (stat(build_unix_name(&nwlogin, 0), &stbuff)) {
errorp(1, "Stat error LOGIN Directory, Abort !!",
"UnixPath=`%s`", build_unix_name(&nwlogin, 0));
@ -1523,6 +1583,13 @@ int nw_free_handles(int task)
}
d++;
}
for (k=0; k < anz_dirhandles; k++){
DIR_HANDLE *dh=&(dir_handles[k]);
if (dh->f) {
closedir(dh->f);
dh->f=NULL;
}
}
init_file_module(task);
}
return(0);
@ -1596,6 +1663,25 @@ int nw_search(uint8 *info, uint32 *fileowner,
} else return(completition); /* wrong path */
}
int nw_dir_get_vol_path(int dirhandle, uint8 *path)
/* returns volume or error ( < 0) */
{
int result;
NW_DIR *dir = (dirhandle > 0 && dirhandle <= used_dirs)
? &(dirs[dirhandle-1])
: NULL;
if (dir && dir->inode) {
int llen = strlen(dir->path);
uint8 *p = path+llen;
result = dir->volume;
memcpy(path, dir->path, llen+1);
if (llen && *(p-1) == '/')
*(p-1) = '\0';
if (result < 0) result = -0x98; /* wrong volume */
} else result = -0x9b;
return(result);
}
int nw_dir_search(uint8 *info,
int dirhandle, int searchsequence,
int search_attrib, uint8 *data, int len)
@ -1608,9 +1694,9 @@ int nw_dir_search(uint8 *info,
DIR_HANDLE *dh = &(dir_handles[dirhandle]);
struct stat stbuff;
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) {
downstr(nwpath.fn);
down_fn(nwpath.fn);
} else {
upstr(nwpath.fn);
up_fn(nwpath.fn);
}
if (get_dh_entry(dh,
nwpath.fn,
@ -1671,7 +1757,7 @@ int nw_open_dir_handle( int dir_handle,
if (completition > -1) {
struct stat stb;
DIR_HANDLE *dh = &(dir_handles[completition-1]);
stat(dh->unixname, &stb);
s_stat(dh->unixname, &stb, NULL);
*volume = dh->volume;
*dir_id = completition;
*searchsequence = MAX_U16;
@ -1743,7 +1829,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);
up_fn(name);
} else result = -0x98;
}
XDPRINTF((5,0,"nw_get_directory_path:%s: Handle=%d, result=0x%x", name, dir_handle+1, result));
@ -1773,7 +1859,7 @@ int nw_get_eff_dir_rights(int dir_handle, uint8 *data, int len, int modus)
(modus) ? 0 : 1);
if (completition < 0) return(completition);
strcpy(unname, build_unix_name(&nwpath, 0));
if (stat(unname, &stbuff) ||
if (s_stat(unname, &stbuff, NULL) ||
(!modus && !S_ISDIR(stbuff.st_mode)) ) {
completition = -0x9c;
} else completition=un_nw_rights(&stbuff); /* eff. rights */
@ -1822,9 +1908,9 @@ static int s_nw_scan_dir_info(int dir_handle,
if (!dirsequenz) dirsequenz++;
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) {
downstr(wild);
down_fn(wild);
} else {
upstr(wild);
up_fn(wild);
}
strcpy((char*)dirname, (char*)wild);
@ -1842,7 +1928,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);
up_fn(dirname);
strncpy((char*)subname, (char*)dirname, 16);
U32_TO_BE32(get_file_owner(&stbuff), owner);
un_date_2_nw(stbuff.st_mtime, subdatetime, 1);
@ -1854,7 +1940,7 @@ static int s_nw_scan_dir_info(int dir_handle,
} else {
*(dh->kpath) = '.';
*(dh->kpath+1) = '\0';
if (!stat(dh->unixname, &stbuff)) {
if (!s_stat(dh->unixname, &stbuff, NULL)) {
U16_TO_BE16(1, subnr);
memset(subname, 0, 16);
U32_TO_BE32(get_file_owner(&stbuff), owner);
@ -1905,13 +1991,13 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
int voloptions=get_volume_options(volume, 1);
f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12);
upstr(spath);
up_fn(spath);
strncpy((char*)f->name, (char*)spath, f->namlen);
/* Attribute */
/* 0x20 Archive Flag */
/* 0x80 Sharable */
if (voloptions & VOL_OPTION_IS_PIPE)
f->attributes[0] = 0;
f->attributes[0] = FILE_ATTR_SHARE;
else
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
un_date_2_nw(stb->st_mtime, f->created.date, 0);
@ -1934,7 +2020,7 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
uint8 spath[14];
f->namlen=min(strlen((char*)path), 12);
strmaxcpy(spath, path, 12);
upstr(spath);
up_fn(spath);
strncpy((char*)f->name, (char*)spath, f->namlen);
f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0);
un_date_2_nw(stb->st_mtime, f->created.date,0);
@ -1995,7 +2081,7 @@ int nw_scan_a_root_dir(uint8 *rdata,
nwpath.path, nwpath.fn, completition));
if (completition > -1) {
struct stat stbuff;
if (!stat(build_unix_name(&nwpath, 2), &stbuff)) {
if (!s_stat(build_unix_name(&nwpath, 2), &stbuff, NULL)) {
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.volume, nwpath.fn);
@ -2016,8 +2102,7 @@ static int my_match(uint8 *s, uint8 *p)
} else if (dot) {
if (dot++ > 3) return(0);
} else if (len == 8) return(0);
if (*s != *p && ((!isalpha(*p)) || (!isalpha(*s))
|| (*p | 0x20) != (*s | 0x20)))
if (!ufn_imatch(*s, *p))
return(0);
++len;
}
@ -2079,7 +2164,7 @@ 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 */
if (!s_stat(unixname, &stb, NULL)) /* path is ok I hope */
return;
get_match(unixname, pp-1);
}

View File

@ -1,4 +1,4 @@
/* connect.h 06-Nov-96 */
/* connect.h 02-Jun-97 */
#ifndef _CONNECT_H_
#define _CONNECT_H_
@ -24,20 +24,6 @@
#define FILE_ATTR_A 0x00000020
#define FILE_ATTR_SHARE 0x00000080
typedef struct {
DIR *f;
char unixname[256]; /* kompletter unixname */
ino_t inode; /* Unix Inode */
time_t timestamp; /* f<>r letzte Allocierung */
char *kpath; /* Ein Zeichen nach unixname */
int vol_options; /* searchoptions */
int volume; /* Volume Number */
int sequence; /* Search sequence */
off_t dirpos; /* Current pos in unix dir */
} DIR_HANDLE;
typedef struct {
uint8 path[256]; /* directory */
uint8 fn[256]; /* file */
@ -45,16 +31,6 @@ typedef struct {
int has_wild; /* fn has wildcards */
} NW_PATH;
typedef struct {
ino_t inode; /* Unix Inode dieses Verzeichnisses */
time_t timestamp; /* Zeitmarke */
uint8 *path; /* path ab Volume */
uint8 volume; /* Welches Volume */
uint8 is_temp; /* 0:perm. 1:temp 2: spez. temp */
uint8 drive; /* driveletter */
uint8 task; /* actual task */
} NW_DIR;
typedef struct {
uint8 name[14]; /* filename in DOS format */
uint8 attrib; /* Attribute */
@ -130,6 +106,11 @@ typedef struct {
} u;
} NW_SCAN_DIR_INFO;
extern int use_mmap;
extern int tells_server_version;
extern int max_burst_send_size;
extern int max_burst_recv_size;
extern int nw_init_connect(void);
extern void nw_exit_connect(void);
@ -157,6 +138,8 @@ extern int nw_search(uint8 *info, uint32 *fileowner,
int dirhandle, int searchsequence,
int search_attrib, uint8 *data, int len);
extern int nw_dir_get_vol_path(int dirhandle, uint8 *path);
extern int nw_dir_search(uint8 *info,
int dirhandle, int searchsequence,
int search_attrib, uint8 *data, int len);
@ -220,8 +203,6 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
#define MAX_NW_DIRS 255
extern NW_DIR dirs[MAX_NW_DIRS];
extern int used_dirs;
extern int act_uid;
extern int act_gid;
extern int act_obj_id; /* not login == 0 */
@ -264,8 +245,6 @@ extern int un_nw_rights(struct stat *stb);
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

@ -1,4 +1,4 @@
/* debmask.h: 15-Feb-97 */
/* debmask.h: 18-Jun-97 */
#ifndef _DEBMASK_H_
#define _DEBMASK_H_
/*
@ -12,6 +12,7 @@
#define D_FH_LOCK 2 /* file lock/unlock */
#define D_FH_FLUSH 4 /* file flushes */
#define D_FN_NAMES 8
#endif

View File

@ -1,6 +1,6 @@
Sorry, this is in German only.
User important notes are in the NEWS file.
Aenderungen in mars_nwe bis zum : 16-Apr-97
Aenderungen in mars_nwe bis zum : 07-Jul-97
--------------------------------
Erste 'oeffentliche' Version
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -291,4 +291,39 @@ Erste 'oeffentliche' Version
- Result code von nw_lock_file() korrigiert (0x21 -> 0xfd).
( MS-Access meckerte unter Win3.xx fehlendes SHARE.EXE an )
<----- ^^^^^^^^^^ pl10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Workaround gegen 'fehlerhaftes' telldir()/seekdir() (NFS-FS) eingebaut.
Fehler bewirkte Endlosloop beim 'Dir-Listen'.
Hinweis von Thomas Behr.
Search Dir Routine in namespace.c umgeschrieben.
- Syslogstuff nach Idee von Thomas Behr eingebaut.
- Es bleibt nun nur noch max. 1 DIR* handle / connection geoeffnet.
- erste Testimplementation des Burstmodus.
- Cyrillic Filename Support von Victor Khimenko eingebaut.
- Max. moegliche Connections auf > 255 erhoeht.
Muss aber noch richtig getestet werden.
- Dateimatchroutine OS/2 namespace wiederum abgeaendert.
Es wurde bei Matchcode '0xff * 0xff 0xae 0xff *' keine Datei
ohne '.' gefunden.
- Attribute von 'Pipe Commands' ist nun Shareble.
Dadurch sollten Client Bufferungen verhindert werden.
- einige Konstanten aus config.h sind nun auch zur Laufzeit
aenderbar. ab section 60 in ini/conf file.
- Konstanten MAX_NW_ROUTES, MAX_NW_SERVERS, MAX_RIP_ENTRIES,
MAX_NET_DEVICES werden nicht mehr benoetigt, da entsprechende
Arrays nun bei Bedarf dynamisch wachsen.
- nw_2_un_time Routine setzt nun auch die Sekunden korrekt.
Hinweis/Patch von Csoma Csaba.
- Im lock call wird nun bei Locksize von MAX_U32 komplette Datei
ab Offset gelockt. ( von Peter Gerhard )
- In connect.c, build_verz_name() Fehlerabfang fuer 'falsche Dateinamen'
korrigiert. (Victor Khimenko schickte patch)
Es war moeglich auf 9 stellige (ohne Punkt) Verzeichnissnamen
zuzugreifen.
- examples/unxcomm.c korrigiert.
- es wird nun der Login Name oder '()' fuer attached unter ps
angezeigt.
- in routine nw_2_un_time() wird nun tm_isdst korrekterweise
auf -1 gesetzt.
- dynamisches Aktivieren/Deaktivieren von Interfaces verbessert.
<----- ^^^^^^^^^^ pl11 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -3,6 +3,9 @@ Sorry, but this list will *never* be complete.
Michael Beddow <m.beddow@servelan.co.uk>
translated doc for PIPE-FS
Thomas Behr <Thomas.Behr@uvw.uni-bayreuth.de>
testings, wrote syslog stuff
Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
testing router code on token ring
wrote the 'crypted change password' routines !
@ -10,18 +13,27 @@ Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
many testings+notes
Arne de Bruijn <arne@arne.bilt>
Arne de Bruijn <arne@knoware.nl>
testings, exploring ncp mysterius (netx), notes
Hardy Buchholz <hardy@kool.f.eunet.de>
wrote HOWTO.ger
Csoma Csaba <csoma@usa.net>
testings+bugfixes
Ales Dryak <A.Dryak@sh.cvut.cz>
his linware gave the kick
Fritz Elfert <fritz@wuemaus.franken.de>
gives bugreport and patches
Peter Gerhard <pgerhard@jpn.tuv.com>
testings, bugreport, patches.
Victor Khimenko <khim@mccme.ru>
cyrillic filename patches
Ruedi Kneubuehler <pingu@satu.baboon.ch>
helping and testing for linux/sparc

View File

@ -1,3 +1,14 @@
------07-Jul-97--- 0.98.pl11 ---------
- section 201 enhanced -> syslogd
- new section 50: filenametranslation by Victor Khimenko.
- some new sections >= 60 to runtime modify some compiled in options.
MAX_NW_SERVERS, MAX_NW_ROUTES, MAX_RIP_ENTRIES, MAX_NET_DEVICES are
not used/needed anymore (dynamic allocation now).
- a 'ps' now shows logged in user like
.... nwconn 1 0.0.0.10:0.80.48.83.14.3f:40.4 MAR
and a 'attached only' session like
.... nwconn 1 0.0.0.10:0.80.48.83.14.3f:40.4 ()
- now mars_nwe can handle more than 255 connections ( I hope ;-) )
------17-Apr-97--- 0.98.pl9 ----------
- Section 4: IPX-Devices, syntax of automatic creation of interfaces and
- Section 5: save flag -> device flags CHANGED !!

31
doc/README.NLS Normal file
View File

@ -0,0 +1,31 @@
Now MASR_NWE contains ALPHA code for support NLS.
This support is not based on standard libc definitions for some reasons
(the most important is that libc cannot handle two encodings). This complex
scheme was designed especially for support of ex-USSR (where for historical
reasons in DOS world cyrillic letters has other codes then in Linux world ;)
Really now this code was tested only on one comp (sch57.mccme.ru ;) with
following combination of codepages: external (DOS) encoding -- cp866,
internal (Linux) encoding -- KOI8-R. With this option enabled all NAMES of
files (not contents yet) will be converted before storing on disk from external
encoding (cp866 in our case) to internal encoding and converted backword when
directory will be scanned... Also filenames will be converted to lowercase if
you set the 'k' options and converted to uppercase if you not set both 'k'
options and 'i' options in section 1 (volumes).
For support all this transformations you must create four tables (in one file,
one after one): first -- for converting from extenal encoding to internal,
second -- reversed table, third -- for doing UPCASE in external encoding and
tha last -- for doing lowercase in external encoding. There are now three good
start point:
1. nw.ini.cnv.min -- only ASCII table supported (good starting point)
2. nw.ini.cnv.437 -- for default linux and charset
3. nw.ini.cnv.cyr -- external encoding -- cp866, internal -- koi8-r
You can edit this files with any editor, which can handle BINARY file (I know
that joe and mcedit do so).
P.S. I think about converting CONTENTS of files automatically, but I think that
this MUST be option in section 1 for such conversion...
khim@sch57.mccme.ru

View File

@ -1,7 +1,7 @@
Begin3
Title: mars_nwe
Version: 0.98.pl10
Entered-date: 24-Apr-97
Version: 0.98.pl11
Entered-date: 07-Jul-97
Description: Full netware-emulator (src), beta.
Supports file-services, bindery-services,
printing-services, routing-services.
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@stover.f.eunet.de (Martin Stover)
Maintained-by: mstover@stover.f.eunet.de (Martin Stover)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
200kB mars_nwe-0.98.pl10.tgz
200kB mars_nwe-0.98.pl11.tgz
Alternate-site: sunsite.unc.edu:/pub/Linux/system/filesystems/ncpfs
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
Copying-policy: GNU

View File

@ -1,5 +1,4 @@
#define DO_IPX_SEND_TEST 1
/* emutli.c 04-Oct-96 */
/* emutli.c 07-Jul-97 */
/*
* One short try to emulate TLI with SOCKETS.
*/
@ -37,6 +36,24 @@
#include <string.h>
#include <errno.h>
#ifndef DO_IPX_SEND_TEST
# define DO_IPX_SEND_TEST 2
#endif
/* DO_IPX_SEND_TEST is only needed if the ipx sendmsg() bug is not patched
*
* In linux/net/ipx/af_ipx.c routine ipx_create one line is missing.
*
* static int ipx_create(struct socket *sock, int protocol)
* {
* ...
* sk->rcvbuf=SK_RMEM_MAX;
* sk->sndbuf=SK_WMEM_MAX;
* sk->allocation=GFP_KERNEL;
* .......^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
*/
static int locipxdebug=0;
void set_locipxdebug(int debug)
@ -237,13 +254,13 @@ inline int t_sndudata(int fd, struct t_unitdata *ud)
do {
void (*old_sig)(int rsig) = signal(SIGALRM, sig_alarm);
new_try = 0;
alarm(1+anz_tries);
alarm(DO_IPX_SEND_TEST+anz_tries);
#endif
memset(&ipxs, 0, sizeof(struct sockaddr_ipx));
ipxs.sipx_family=AF_IPX;
ipx2sockadr(&ipxs, (ipxAddr_t*) (ud->addr.buf));
ipxs.sipx_type = (ud->opt.len) ? (uint8) *((uint8*)(ud->opt.buf)) : 0;
result = sendto(fd,(void *)ud->udata.buf,
ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs));

17
examples/README.important Normal file
View File

@ -0,0 +1,17 @@
This is an important kernel ipx patch for all known kernels.
In linux/net/ipx/af_ipx.c routine ipx_create one line is missing.
static int ipx_create(struct socket *sock, int protocol)
{
...
sk->rcvbuf=SK_RMEM_MAX;
sk->sndbuf=SK_WMEM_MAX;
sk->allocation=GFP_KERNEL;
.......^^^^^^^^^^^^^^^^^^^^^^^^^^^
After applying this patch you can disable the sendmsg() workaround code
in mars_nwe/emutli.c by setting DO_IPX_SEND_TEST to 0.
#define DO_IPX_SEND_TEST 0

View File

@ -1,29 +0,0 @@
!! this kernelpatch is _not_ needed for kernel >= 1.3.60 :) !!
this kernelpatch for clean kernels 1.3.56,57,58, pur 59 makes 3 things.
- removes the ipx-send bug. BIG THANKS to Volker Lendecke.
the problem was that sometimes the sendto function hung.
- ipx rip/sap packets comming from internal net must change
there source address from internal net/node to the
device net/node.
The problem was:
By configuring mars_nwe at the internal network, the rip/sap
socket gets the network and node address of the internal
net. Then, by sending rip/sap packets over this socket to the
several devices the rip/sap packets don't have the device net/node,
but the internal net/node.
- an existing route should never be overwritten by an route
over the internal net.
The problem was:
By running dosemu at the same workstation as mars_nwe the
dosemu automaticly changes the route to a nearby server
to route over the internal network and this destroyed
the real route over a device to this server.
You must be supervisor and then you must start './patchme' .
Martin Stover

View File

@ -1,14 +0,0 @@
The kernelpatch kpatch1.3.72 you can use directly for kernels 1.3.72 .. 1.3.77
The kernelpatch kpatch1.3.78 you can use directly for kernels 1.3.78,79 .. ??
but it should be easy to apply this patch to all kernels.
By older kernels 'sk->protinfo.af_ipx.' must become 'sk->' .
After applying this patch please rebuild mars_nwe (make clean)
for getting notice of new ioctl call 'SIOCIPXNCPCONN'.
This patch is only necessary to speed up mars_nwe. (ca. 30 .. 50 % )
Perhaps this patch will get a place in the kerneldistribution one day. :)
This kernelpatch was originally designed by Volker Lendecke.
Martin

View File

@ -1,4 +1,4 @@
/* config.h: 29-Jan-97 */
/* config.h: 02-Jun-97 */
/* some of this config is needed by make, others by cc */
#define DO_DEBUG 1 /* compile in debug code */
@ -31,14 +31,24 @@
#define MAX_CONNECTIONS 5 /* max. number of simultaneous */
/* connections handled by mars_nwe */
/* !! NOTE !! */
/* If set > 255 some NCP calls will probably not work, try it with caution */
/* and you should apply examples/kpatch2.0.29 */
#define IPX_DATA_GR_546 1 /* 0 = max. IPX Packets = 546 +30 Byte ( 512 Byte RWBuff) */
/* 1 = max. IPX packets = 1058 +30 Byte (1024 Byte RWBuff) */
/* 2 = max. IPX packets = 1470 +30 Byte (1444 Byte RWBuff) */
/* 3 = max. IPX packets = 4130 +30 Byte (4096 Byte RWBuff) */
#define ENABLE_BURSTMODE 0 /* 0 = disable burstmode, 1 = enable burstmode */
/* in 0.98.pl11 still NOT working !! */
/* to get Burstmode really enabled, section '6' in conf-file */
/* must be set to a value > 1 (3.12 Server) */
/* and kernel-patch examples/kpatch2.0.29 should be used */
#define USE_MMAP 1 /* use mmap systen call */
#define USE_MMAP 1 /* use mmap systen call, not always best choice */
#if 0
#define SOCK_EXTERN 0x8005 /* creat socket for external access */
@ -59,21 +69,18 @@
/* entry '6' in ini file should be set*/
/* to > '0', too. */
/* <--------------------------------------------------------------------> */
#define MAX_NW_SERVERS 40 /* max. number of nw-servers on your */
/* network */
#define HANDLE_ALL_SAP_TYPS 0 /* if set to 0 only SAP-Typ 4 Servers */
/* will be put into routing table and */
/* if set to 1 all SAP Typs will be */
/* used. */
#define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */
/* main idea from Victor Khimenko */
/* in 0.98.pl11 still NOT working !! */
/* <--------------- next is for linux only ----------------------------> */
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */
/* -------------------- */
#define MAX_NET_DEVICES 5 /* max. Netdevices, frames */
#define MAX_NW_ROUTES 50 /* max. nw-networks on your network */
/* (internal + external) */
#define MAX_RIP_ENTRIES 50 /* max. rip responses */
/* -------------------- */
#define SHADOW_PWD 0 /* change to '1' for shadow passwds */
#define QUOTA_SUPPORT 0 /* change to '1' for quota support */

Binary file not shown.

View File

@ -1,56 +0,0 @@
--- af_ipx.c Sat Jan 6 13:54:59 1996
+++ af_ipx.c Sun Jan 21 20:36:36 1996
@@ -507,8 +507,10 @@
/*
* Don't charge sender
*/
- if(skb->sk)
+ if(skb->sk) {
skb->sk->wmem_alloc-=skb->truesize;
+ skb->sk = NULL;
+ }
/*
* Will charge receiver
*/
@@ -519,8 +521,10 @@
*/
if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
{
- if (!send_to_wire && skb->sk)
+ if (!send_to_wire && skb->sk) {
skb->sk->wmem_alloc-=skb->truesize;
+ skb->sk = NULL;
+ }
ipxitf_demux_socket(intrfc, skb, send_to_wire);
if (!send_to_wire)
return 0;
@@ -994,7 +998,9 @@
return -EAGAIN;
rt->ir_next=ipx_routes;
ipx_routes=rt;
- }
+ } else if (intrfc == ipx_internal_net)
+ /* don't change an existing route to internal net (mars_nwe) */
+ return(0);
rt->ir_net = network;
rt->ir_intrfc = intrfc;
@@ -1108,9 +1114,15 @@
ipx->ipx_tctrl=0;
ipx->ipx_type=usipx->sipx_type;
skb->h.raw = (unsigned char *)ipx;
-
- ipx->ipx_source.net = sk->ipx_intrfc->if_netnum;
- memcpy(ipx->ipx_source.node, sk->ipx_intrfc->if_node, IPX_NODE_LEN);
+
+ if ((err = ntohs(sk->ipx_port)) == 0x453 || err == 0x452) {
+ /* RIP/SAP special handling for mars_nwe */
+ ipx->ipx_source.net = intrfc->if_netnum;
+ memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN);
+ } else {
+ ipx->ipx_source.net = sk->ipx_intrfc->if_netnum;
+ memcpy(ipx->ipx_source.node, sk->ipx_intrfc->if_node, IPX_NODE_LEN);
+ }
ipx->ipx_source.sock = sk->ipx_port;
ipx->ipx_dest.net=usipx->sipx_network;
memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);

View File

@ -1,72 +0,0 @@
Index: include/linux/ipx.h
--- linux.org/include/linux/ipx.h Mon Dec 11 19:55:58 1995
+++ linux/include/linux/ipx.h Thu Mar 21 17:14:49 1996
@@ -74,5 +74,6 @@
#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1)
#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3)
#endif
Index: include/net/sock.h
Prereq: 1.0.4
--- linux.org/include/net/sock.h Mon Mar 11 02:08:59 1996
+++ linux/include/net/sock.h Thu Mar 21 02:36:23 1996
@@ -96,6 +96,7 @@
ipx_address dest_addr;
ipx_interface *intrfc;
unsigned short port;
+ unsigned short ipx_ncp_conn;
#ifdef CONFIG_IPX_INTERN
unsigned char node[IPX_NODE_LEN];
#endif
Index: net/ipx/af_ipx.c
--- linux.org/net/ipx/af_ipx.c Sun Mar 10 22:51:28 1996
+++ linux/net/ipx/af_ipx.c Thu Mar 21 17:26:54 1996
@@ -438,6 +438,20 @@
ipx_socket *sock1 = NULL, *sock2 = NULL;
struct sk_buff *skb1 = NULL, *skb2 = NULL;
+ if (intrfc == ipx_primary_net
+ && ntohs(ipx->ipx_dest.sock) == 0x451
+ && *((char*)(ipx+1)) == 0x22
+ && *((char*)(ipx+1)+1) == 0x22) {
+ int connection = (int) *((char*)(ipx+1)+3);
+ /* 255 connections are enough ;) */
+ if (connection) {
+ for (sock1=intrfc->if_sklist;
+ (sock1 != NULL) &&
+ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
+ sock1=sock1->next);;
+ }
+ }
+ if (sock1 == NULL)
sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
/*
@@ -1628,6 +1642,7 @@
sizeof(sk->protinfo.af_ipx.dest_addr));
sk->protinfo.af_ipx.port = 0;
sk->protinfo.af_ipx.ncp_server = 0;
+ sk->protinfo.af_ipx.ipx_ncp_conn = 0; /* no ncp socket yet */
sk->mtu=IPX_MTU;
if(sock!=NULL)
@@ -2128,6 +2143,17 @@
if(err) return err;
return(ipxcfg_get_config_data((void *)arg));
}
+
+ case SIOCIPXNCPCONN:
+ {
+ if (!suser()) return(-EPERM);
+ err = verify_area(VERIFY_READ, (void *)arg,
+ sizeof(unsigned short));
+ if (err) return err;
+ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg);
+ return 0;
+ }
+
case SIOCGSTAMP:
if (sk)
{

View File

@ -1,74 +0,0 @@
diff -rub linux.org/include/linux/ipx.h linux/include/linux/ipx.h
--- linux.org/include/linux/ipx.h Wed Mar 27 18:43:19 1996
+++ linux/include/linux/ipx.h Thu Mar 28 11:15:31 1996
@@ -74,5 +74,6 @@
#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1)
#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3)
#endif
diff -rub linux.org/include/net/sock.h linux/include/net/sock.h
--- linux.org/include/net/sock.h Wed Mar 27 23:05:18 1996
+++ linux/include/net/sock.h Thu Mar 28 11:15:31 1996
@@ -112,6 +112,10 @@
* know the connection this socket belongs to.
*/
struct ncp_server *ncp_server;
+/*
+ * To handle special NCP-Sockets for mars_nwe
+ */
+ unsigned short ipx_ncp_conn;
};
#endif
diff -rub linux.org/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- linux.org/net/ipx/af_ipx.c Wed Mar 27 17:50:39 1996
+++ linux/net/ipx/af_ipx.c Thu Mar 28 11:15:31 1996
@@ -448,6 +448,20 @@
ipx_socket *sock1 = NULL, *sock2 = NULL;
struct sk_buff *skb1 = NULL, *skb2 = NULL;
+ if (intrfc == ipx_primary_net
+ && ntohs(ipx->ipx_dest.sock) == 0x451
+ && *((char*)(ipx+1)) == 0x22
+ && *((char*)(ipx+1)+1) == 0x22) {
+ int connection = (int) *((char*)(ipx+1)+3);
+ /* 255 connections are enough ;) */
+ if (connection) {
+ for (sock1=intrfc->if_sklist;
+ (sock1 != NULL) &&
+ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
+ sock1=sock1->next);;
+ }
+ }
+ if (sock1 == NULL)
sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
/*
@@ -1639,6 +1653,7 @@
sizeof(sk->protinfo.af_ipx.dest_addr));
sk->protinfo.af_ipx.port = 0;
sk->protinfo.af_ipx.ncp_server = 0;
+ sk->protinfo.af_ipx.ipx_ncp_conn = 0; /* no ncp socket yet */
sk->mtu=IPX_MTU;
if(sock!=NULL)
@@ -2142,6 +2157,17 @@
if(err) return err;
return(ipxcfg_get_config_data((void *)arg));
}
+
+ case SIOCIPXNCPCONN:
+ {
+ if (!suser()) return(-EPERM);
+ err = verify_area(VERIFY_READ, (void *)arg,
+ sizeof(unsigned short));
+ if (err) return err;
+ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg);
+ return 0;
+ }
+
case SIOCGSTAMP:
if (sk)
{

112
examples/kpatch2.0.29 Normal file
View File

@ -0,0 +1,112 @@
diff -ubr 2.0.29/include/linux/ipx.h linux/include/linux/ipx.h
--- 2.0.29/include/linux/ipx.h Mon May 13 22:39:28 1996
+++ linux/include/linux/ipx.h Tue May 27 02:50:48 1997
@@ -75,5 +75,6 @@
#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1)
#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3)
#endif
diff -ubr 2.0.29/include/net/sock.h linux/include/net/sock.h
--- 2.0.29/include/net/sock.h Tue Dec 10 18:35:21 1996
+++ linux/include/net/sock.h Tue May 27 02:50:48 1997
@@ -112,7 +112,11 @@
* know the connection this socket belongs to.
*/
struct ncp_server *ncp_server;
-
+/*
+ * To handle special ncp connection-handling sockets for mars_nwe,
+ * the connection number must be stored in the socket.
+ */
+ unsigned short ipx_ncp_conn;
};
#endif
diff -ubr 2.0.29/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- 2.0.29/net/ipx/af_ipx.c Tue Dec 10 18:35:35 1996
+++ linux/net/ipx/af_ipx.c Tue May 27 02:50:48 1997
@@ -468,7 +468,60 @@
ipx_socket *sock1 = NULL, *sock2 = NULL;
struct sk_buff *skb1 = NULL, *skb2 = NULL;
+ if (intrfc == ipx_primary_net
+ && ntohs(ipx->ipx_dest.sock) == 0x451)
+ {
+ /*
+ * The packet's target is a NCP connection handler. We want to
+ * hand it to the correct socket directly within the kernel,
+ * so that the mars_nwe packet distribution process
+ * does not have to do it. Here we only care about NCP and
+ * BURST packets.
+ * You might call this a hack, but believe me, you do not
+ * want a complete NCP layer in the kernel, and this is
+ * VERY fast as well.
+ */
+ int connection = 0;
+
+ if ( *((char*)(ipx+1)) == 0x22
+ && *((char*)(ipx+1)+1) == 0x22)
+ {
+ /*
+ * The packet is a NCP request
+ */
+ connection = ( ((int) *((char*)(ipx+1)+5)) << 8 )
+ | (int) *((char*)(ipx+1)+3);
+ }
+ else if ( *((char*)(ipx+1)) == 0x77
+ && *((char*)(ipx+1)+1) == 0x77)
+ {
+ /*
+ * The packet is a BURST packet
+ */
+ connection = ( ((int) *((char*)(ipx+1)+9)) << 8 )
+ | (int) *((char*)(ipx+1)+8);
+ }
+
+ if (connection)
+ {
+ /*
+ * Now we have to look for a special NCP connection handling
+ * socket. Only these sockets have ipx_ncp_conn != 0, set
+ * by SIOCIPXNCPCONN.
+ */
+ for (sock1=intrfc->if_sklist;
+ (sock1 != NULL) &&
+ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
+ sock1=sock1->next);;
+ }
+ }
+ if (sock1 == NULL)
+ {
+ /* No special socket found, forward the packet the
+ * normal way.
+ */
sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
+ }
/*
* We need to check if there is a primary net and if
@@ -2242,6 +2295,21 @@
if(err) return err;
return(ipxcfg_get_config_data((void *)arg));
}
+
+ case SIOCIPXNCPCONN:
+ {
+ /*
+ * This socket wants to take care of the NCP connection
+ * handed to us in arg.
+ */
+ if (!suser()) return(-EPERM);
+ err = verify_area(VERIFY_READ, (void *)arg,
+ sizeof(unsigned short));
+ if (err) return err;
+ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg);
+ return 0;
+ }
+
case SIOCGSTAMP:
if (sk)
{

View File

@ -2,9 +2,14 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux.
#
# last changed: 10-Apr-97
# last changed: 07-Jul-97
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
#
# since version 0.98.pl11:
# the most important options in config.h can now be altered in
# this file begin at section 60.
# This file specifies which Linux-resources (printers, users, directories)
# should be accessible to the DOS-clients via "mars_nwe". Furthermore
# some general parameters are configured here.
@ -42,8 +47,8 @@
# /var/local/nwe/SYS -------> SYS -------------> W:
#
# More than one entry is allowed in this section.
# The maximum number of volumes is a compile-time option that must be
# specified in `config.h' before compiling mars_nwe.
# The maximum number of volumes must be specified in `config.h'
# or in section 61 in this file.
#
# Please note that at least the volume "SYS" must be defined and it must
# contain the following sub-directories: LOGIN, PUBLIC, SYSTEM, MAIL.
@ -70,7 +75,6 @@
# should only be used if you really need it.
# 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) or volumes, which
# should be remountable when mars_nwe is running.
# Should also be used for 'HOME' volumes.
@ -86,8 +90,9 @@
# See `doc/PIPE-FS'.
#
# additional Namespaces
# O + OS/2 namespace (useful for Win95 clients, see doc/FAQS).
# N + NFS namespace.
# O (uppercase o)
# + OS/2 namespace (useful for Win95 clients, see doc/FAQS).
# N + NFS namespace (not really tested).
# -------------------------------------------------------------------------
#
# Examples:
@ -204,13 +209,14 @@
#
# FRAME: the frame-type of the data-packets on your local network.
# Possible values are:
# ethernet_ii
# 802.2
# 802.3 (default)
# snap
# token
# auto automatic detection of the frame-type used
# in your ipx-environment
#
# ethernet_ii :best for mixed(ipx, ip) environments
# 802.2 :Novell uses this as default since 3.12
# 802.3 :older frame typ, some boot proms use it
# snap :normally not used
# token :for token ring cards
# auto :automatic detection of the frame-type used
# in your ipx-environment
#
# TICKS: the time data-packets need to get delivered over a
# certain interface. If your connection goes through several
@ -271,8 +277,11 @@
# 2 Version 3.12 (burst mode is not implemented yet)
#
# If you want to use longfilenamesupport and/or namespace routines
# you should set this section to '1'.
# you should set this section to '1' or '2'
# And you should read doc/FAQS.
# If you want to test Burst mode this section must be set to '2'
# and in config.h you must set ENABLE_BURSTMODE to 1.
#
# -------------------------------------------------------------------------
#
@ -448,6 +457,8 @@
# See section 12 for a description of the syntax.
#
# Unlike in section 12, you can define users with no password.
# If you explizit want to set 'no password' here then use
# a '-' sign as password.
# -------------------------------------------------------------------------
# Syntax:
# 13 NW_LOGIN LINUX_LOGIN [PASSWORD] [FLAGS]
@ -459,6 +470,7 @@
# 13 MARTIN martin
# 13 DAREK martin
# 13 COMMON common gast 0x1 # no password change by user.
# 13 COMMON common 0x1 # syntax is allowed too.
# Section 14: currently not used
@ -558,6 +570,46 @@
# -------------------------------------------------------------------------
# =========================================================================
# Section 30: Burst mode values (optional)
#
# -------------------------------------------------------------------------
# Syntax:
# 30 MAX_BURST_READ_BUF MAX_BURST_WRITE_BUF
# default is 0x2000 0x2000
# Examples:
# 30 0x2000 0x2000
# =========================================================================
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
# Tables for DOS->Unix names translation & upper/lowercase translations
# For more information see doc/README.NLS
# some examples files exist in the examples directory.
# Conversation file must include 4 tables a 256 byte.
# 0 = dos2unix
# 1 = unix2dos
# 2 = down2up 'dosname'
# 3 = up2down 'dosname'
# -------------------------------------------------------------------------
# Syntax:
# 50 Filename of conversation file.
#
# Examples:
# 50 /etc/nwserv.cnv
# Changing defaults from config.h
# more information in config.h
# 60 10 # MAX_CONNECTIONS
# 61 10 # MAX_NW_VOLS
# 68 1 # USE_MMAP (use mmap=1, no mmap=0)
# 69 0 # HANDLE_ALL_SAP_TYPS (all sap typs=1, only typ 4=0)
# 70 0x44444444 # NETWORK_SERIAL_NMBR (4 byte)
# 71 0x2222 # NETWORK_APPL_NMBR (2 byte)
# --------------------------------------------------------
# You usally don't want to change anything below this line
@ -584,7 +636,15 @@
200 1 # 0 = no logfile and dont daemonize nwserv/nwrouted
# 1 = daemonize nwserv/nwrouted and use logfile
201 /tmp/nw.log # filename of logfile
202 1 # 1=creat new logfile, 0=append to logfile
#201 syslog # if filename == syslog then syslogd will be used for
# all messages
202 0x1 # flag in hex notation
# 0x0=append all messages to logfile.
# & 0x1=creat new logfile instead of appending.
#202 0x3 # & 0x2=use syslogd for error messages instead of logfile.
# Sections 210,211: timing

BIN
examples/nw.ini.cnv.437 Normal file

Binary file not shown.

BIN
examples/nw.ini.cnv.cyr Normal file

Binary file not shown.

BIN
examples/nw.ini.cnv.min Normal file

Binary file not shown.

View File

@ -1,20 +0,0 @@
#!/bin/sh
### !!!!!!! this is only for kernel 1.3.56 !!!!!!!!
ACT_DIR=`pwd`
PATCHFILE=kpatch1.3.56
LINUXDIR=/usr/src/linux
IPXDIR=$LINUXDIR/net/ipx
IPXFILE=af_ipx.c
if [ -r $IPXDIR/$IPXFILE ] ; then
if [ -r $IPXDIR/P1 ] ; then
echo "patch was allready made: $IPXDIR/P1 exist"
else
cd $IPXDIR && cp -a $IPXFILE $IPXFILE.org && \
patch < $ACT_DIR/$PATCHFILE && echo "$PATCHFILE" > $IPXDIR/P1
echo "please rebuild the kernel"
fi
else
echo "linuxdir $LINUXDIR perhaps wrong ?"
fi

View File

@ -1,6 +1,6 @@
/* unxcomm.c 24-Oct-96 */
/* unxcomm.c 08-Jun-97 */
/* simple UNX program to work together with 'comm' */
/* to domonstrate usage of pipefilesystem */
/* to demonstrate usage of pipefilesystem */
#include <stdio.h>
#include <fcntl.h>
@ -51,8 +51,8 @@ int bl_read(int fd, void *buf, int size)
int result;
FD_ZERO(&fdin);
FD_SET(fd, &fdin);
t.tv_sec = 1; /* 1 sec should be enough */
t.tv_usec = 0;
t.tv_sec = 0;
t.tv_usec = 100; /* 100 msec should be enough */
result = select(fd+1, &fdin, NULL, NULL, &t);
if (result > 0)
result=read(fd, buf, size);
@ -61,11 +61,16 @@ int bl_read(int fd, void *buf, int size)
int main(int argc, char *argv[])
{
int size;
int size=0;
int l;
char buf[MAXARGLEN+1024];
close(2);
dup2(1,2);
if (0 < (size=bl_read(0, buf, MAXARGLEN))){
while (0 < (l=bl_read(0, buf+size, MAXARGLEN-size)))
size+=l;
if ( 0 < size) {
char **argvv=build_argv(sizeof(buf), buf, size);
if (argvv) {
char path[300];

72
examples/xsockrt.c Normal file
View File

@ -0,0 +1,72 @@
/* (C)opyright (C) 1997 Martin Stover, Marburg, Germany
* simple program for adding/deleting ipx-routes for special sockets
* e.g. for playing doom around ipx-networks.
* needs special linux/net/ipx/af_ipx.c patch !!
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <strings.h>
#include <linux/ipx.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
static int usage(char *prog)
{
char *p=strrchr(prog, '/');
if (p==NULL)p=prog;
else p++;
fprintf(stderr, "usage:\t%s add|del [socknr] \n", p);
fprintf(stderr, "\tsocknr defaults to 0x869b (doom)\n");
fprintf(stderr, "\tother known sockets are:\n");
fprintf(stderr, "\t-0x8813 virgin games, Red Alert\n");
fprintf(stderr, "\tdel 0 removes all socknr !!\n");
return(1);
}
static int handle_ioctl(int mode, int socknr)
{
int fd = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
int result=0;
if (fd > -1) {
if (mode == 1 || !mode) {
result = ioctl(fd, (mode==1) ? SIOCPROTOPRIVATE+4
: SIOCPROTOPRIVATE+5,
&socknr);
} else result++;
if (result==-1) {
perror("ioctl");
result=2;
}
close(fd);
} else {
result++;
perror("open socket");
}
return(result);
}
int main(int argc, char *argv[])
{
int socknr=0x869b;
if (argc < 2)
return(usage(argv[0]));
if (argc > 2 && 1 != sscanf(argv[2],"%i", &socknr))
return(usage(argv[0]));
if (!strncasecmp(argv[1], "add", 3)) {
if (!socknr)
return(usage(argv[0]));
return(handle_ioctl(1, socknr));
} else if (!strncasecmp(argv[1], "del", 3)) {
return(handle_ioctl(0, socknr));
} else
return(usage(argv[0]));
}

View File

@ -1,5 +1,5 @@
#if 0
#makefile.unx 18-Apr-97
#makefile.unx 24-Apr-97
#endif
VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0
V_L=98
P_L=10
P_L=11
#define D_P_L 1
DISTRIB=mars_nwe
@ -113,7 +113,7 @@ PROGS=$(INSTALLPROGS) $(PROG8)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
nwqueue$(O) nameos2$(O)
nwqueue$(O) nameos2$(O) nwfname$(O)
OBJ4= $(OBJ1)
OBJ5= $(OBJ1)
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O)
@ -133,30 +133,30 @@ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \
#if 0
#$(PROG1): $(PROG1)$(O) $(OBJ1)
# $(CC) -o $(VPATH)/$(PROG1) $(PROG1)$(O) $(OBJ1) $(NSLLIB)
# $(CC) -o $(VPATH)/$(PROG1) $(PROG1)$(O) $(OBJ1) $(CRYPTLIB) $(NSLLIB)
#endif
$(PROG2): $(PROG2)$(O) $(OBJ2)
$(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(NSLLIB)
$(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(CRYPTLIB) $(NSLLIB)
#if 0
#$(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(NDBMLIB) $(NSLLIB)
#$(CC) -o $(VPATH)/$(PROG2) $(PROG2)$(O) $(OBJ2) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB)
#endif
$(PROG3): $(PROG3)$(O) $(OBJ3)
$(CC) -o $(VPATH)/$(PROG3) $(PROG3)$(O) $(OBJ3) $(NSLLIB)
$(CC) -o $(VPATH)/$(PROG3) $(PROG3)$(O) $(OBJ3) $(CRYPTLIB) $(NSLLIB)
$(PROG4): $(PROG4)$(O) $(OBJ4)
$(CC) -o $(VPATH)/$(PROG4) $(PROG4)$(O) $(OBJ4) $(NSLLIB)
$(CC) -o $(VPATH)/$(PROG4) $(PROG4)$(O) $(OBJ4) $(CRYPTLIB) $(NSLLIB)
$(PROG5): $(PROG5)$(O) $(OBJ5)
$(CC) -o $(VPATH)/$(PROG5) $(PROG5)$(O) $(OBJ5) $(NSLLIB)
$(CC) -o $(VPATH)/$(PROG5) $(PROG5)$(O) $(OBJ5) $(CRYPTLIB) $(NSLLIB)
$(PROG6): $(PROG6)$(O) $(OBJ6)
$(CC) -o $(VPATH)/$(PROG6) $(PROG6)$(O) $(OBJ6) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB)
$(PROG7): $(PROG7)$(O) $(OBJ7)
$(CC) -o $(VPATH)/$(PROG7) $(PROG7)$(O) $(OBJ7) $(NSLLIB)
$(CC) -o $(VPATH)/$(PROG7) $(PROG7)$(O) $(OBJ7) $(CRYPTLIB) $(NSLLIB)
$(PROG8): $(PROG8)$(O) $(OBJ8)
$(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB)

View File

@ -1,4 +1,4 @@
/* nameos2.c 08-Aug-96 : NameSpace OS2 Services, mars_nwe */
/* nameos2.c 14-May-97 : 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
@ -23,6 +23,7 @@
#include <errno.h>
#endif
#include "nwfname.h"
#include "nwvolume.h"
#include "connect.h"
#include "nwfile.h"
@ -64,8 +65,7 @@ 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)))
if (!ufn_imatch(*s, *p))
return(0);
++len;
}
@ -163,6 +163,32 @@ void mangle_os2_name(NW_VOL *vol, uint8 *unixname, uint8 *pp)
#endif
}
static inline int get_n_p(uint8 **p)
{
int pc=**p;
(*p)++;
if (pc == '\\') {
pc=**p;
(*p)++;
} else if (pc == 255) {
pc=**p;
(*p)++;
switch (pc) {
case 0xaa :
case '*' : return(3000); /* star */
case 0xae :
case '.' : return(1000); /* point */
case 0xbf :
case '?' : return(2000); /* ? */
default : break;
}
}
return(pc);
}
int fn_os2_match(uint8 *s, uint8 *p, int soptions)
/* OS/2 name matching routine */
{
@ -171,7 +197,7 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
int anf, ende;
int not = 0;
uint found = 0;
while ( (pc = *p++) != 0) {
while ( (pc = get_n_p(&p)) != 0) {
if (!(soptions & VOL_OPTION_IGNCASE)) {
if (soptions & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */
if (*s >= 'A' && *s <= 'Z') return(0);
@ -181,21 +207,6 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
}
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++))
@ -208,13 +219,26 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
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;
case 3000: {
uint8 *pp;
int np;
if (!*p) return(1); /* last star */
while (*s) {
if (fn_os2_match(s, p, soptions) == 1) return(1);
else if (*s=='.') {
pp=p;
if (!get_n_p(&p) || !get_n_p(&p))
return(0);
p=pp;
}
++s;
}
pp=p;
np=get_n_p(&p);
p=pp;
if (np == '.' || np == 1000)
return(fn_os2_match(s, p, soptions));
}
if (*p == '.') return(fn_os2_match(s, p, soptions));
return(0);
case '[' : if ( (*p == '!') || (*p == '^') ){
@ -225,10 +249,7 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
continue;
default : if (soptions & VOL_OPTION_IGNCASE) {
if ( pc != *s &&
( (!isalpha(pc))
|| (!isalpha(*s))
|| (pc | 0x20) != (*s | 0x20) ) )
if (!dfn_imatch(*s, *p))
return(0);
} else if (pc != *s) return(0);
++s;
@ -267,6 +288,4 @@ int fn_os2_match(uint8 *s, uint8 *p, int soptions)
if (*s=='.' && *(s+1)=='\0') return(1);
return ( (*s) ? 0 : 1);
}
#endif

View File

@ -1,4 +1,4 @@
/* namspace.c 16-Apr-97 : NameSpace Services, mars_nwe */
/* namspace.c 14-May-97 : NameSpace Services, mars_nwe */
/* !!!!!!!!!!!! NOTE !!!!!!!!!! */
/* Its still very dirty, but it should work fairly well */
@ -27,6 +27,7 @@
#include <errno.h>
#endif
#include "nwfname.h"
#include "nwvolume.h"
#include "connect.h"
#include "nwfile.h"
@ -39,6 +40,11 @@
#define NW_PATH /* */
#if 0
# undef MAX_DIR_BASE_ENTRIES
# define MAX_DIR_BASE_ENTRIES 10
#endif
typedef struct {
int volume; /* Volume Number */
int has_wild; /* fn has wildcards */
@ -60,7 +66,12 @@ typedef struct {
int slot; /* act slot in table */
int locked; /* if locked then do not remove */
/* and do not move till end */
N_NW_PATH nwpath;
/* next is for Direktories, used by the search dir calls */
off_t dirpos; /* last readdirpos */
ino_t found_inode; /* last found inode at readdirpos*/
int sequence; /* last sequence */
N_NW_PATH nwpath;
} DIR_BASE_ENTRY;
static DIR_BASE_ENTRY *dir_base[MAX_DIR_BASE_ENTRIES];
@ -137,13 +148,8 @@ static char *xnwpath_2_unix(N_NW_PATH *nwpath, int modus,
len += len_extra;
}
*p = '\0';
#if 0
if (nwpath->namespace == NAME_DOS) {
if (nw_volumes[volume].options & VOL_OPTION_DOWNSHIFT)
downstr((uint8*)pp);
}
#endif
}
dos2unixcharset(unixname);
if (!allocate_extra) {
xfree(last_unixname);
last_unixname=unixname;
@ -354,6 +360,7 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath,
} /* else */
} /* while */
if (nwpath->volume < 0) result=-0x9c; /* wrong path */
leave_build_nwpath:
if ((!result) && (!act_obj_id) && !(entry8_flags & 1)) {
if (nwpath->volume)
@ -363,7 +370,7 @@ leave_build_nwpath:
char pp[10];
while (*p=='/') ++p;
strmaxcpy(pp, p, 6);
upstr(pp);
up_fn(pp);
p=pp+5;
if (memcmp(pp, "LOGIN", 5) || (*p!='\0' && *p!='/') )
result=-0x9c;
@ -378,23 +385,31 @@ leave_build_nwpath:
uint8 unixname[1024]; /* should be enough */
memcpy(unixname, v->unixname, v->unixnamlen);
strcpy(unixname+v->unixnamlen, nwpath->path);
pp=unixname+v->unixnamlen+npbeg;
pp=unixname+v->unixnamlen;
if (nwpath->namespace == NAME_OS2) {
dos2unixcharset(pp);
pp+=npbeg;
mangle_os2_name(v, unixname, pp);
if (nplen > 0)
if (nplen > 0) {
unix2doscharset(pp);
memcpy(nwpath->path+npbeg, pp, nplen);
}
XDPRINTF((5,0, "Mangle OS/2 unixname='%s'", unixname));
} else if (nwpath->namespace == NAME_DOS) {
dos2unixcharset(pp);
pp+=npbeg;
mangle_dos_name(v, unixname, pp);
if (nplen > 0)
if (nplen > 0) {
unix2doscharset(pp);
memcpy(nwpath->path+npbeg, pp, nplen);
}
XDPRINTF((5,0, "Mangle DOS unixname='%s'", unixname));
}
} else {
if (v->options & VOL_OPTION_DOWNSHIFT)
downstr(nwpath->path);
down_fn(nwpath->path);
else
upstr(nwpath->path);
up_fn(nwpath->path);
#if 0
if (nwpath->namespace == NAME_DOS){
@ -493,6 +508,7 @@ static int find_base_entry(int volume, uint32 basehandle)
return(add_dbe_entry(dnm.namespace, volume, basehandle, NULL, &statb));
}
}
XDPRINTF((1, 0, "Could not find path of vol=%d, base=0x%x", volume, basehandle));
return(-0x9b);
}
@ -568,21 +584,13 @@ static int build_base(int namespace,
N_NW_PATH *nwpath=&loc_nwpath;
init_nwpath(nwpath, namespace);
if (!nwp->flag) { /* short directory handle */
int dir_handle = (int)nwp->base[0];
NW_DIR *dir = (dir_handle > 0 && dir_handle <= used_dirs)
? &(dirs[dir_handle-1])
: NULL;
if (dir && dir->inode) {
int llen = strlen(dir->path);
uint8 *p = nwpath->path+llen;
nwpath->volume = dir->volume;
memcpy(nwpath->path, dir->path, llen+1);
if (llen && *(p-1) == '/')
*(p-1) = '\0';
result = (nwpath->volume > -1) ? 0 : -0x98;
} else result = -0x9b;
result=nw_dir_get_vol_path((int)nwp->base[0], nwpath->path);
if (result > -1){
nwpath->volume = result;
result=0;
}
XDPRINTF((4, 0, "build_base with short_dir_handle=%d, result=0x%x",
dir_handle, result));
(int)nwp->base[0], result));
} else if (nwp->flag == 1) { /* basehandle */
if (-1 < (result = find_base_entry(nwp->volume, GET_32(nwp->base)))) {
DIR_BASE_ENTRY *e = dir_base[result];
@ -656,7 +664,7 @@ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname)
}
if (is_ok) {
strcpy(fname, e->nwpath.fn);
upstr(fname);
up_fn(fname);
return(strlen(fname));
} else {
return(sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino));
@ -764,6 +772,8 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe,
struct stat *stb=&(nwpath->statb);
int result = 76; /* minimumsize */
uint32 owner = get_file_owner(stb);
int voloptions = get_volume_options(nwpath->volume, 1);
memset(p, 0, result+2);
if (infomask & INFO_MSK_DATA_STREAM_SPACE) {
@ -772,7 +782,9 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe,
p += 4;
if (infomask & INFO_MSK_ATTRIBUTE_INFO) {
uint32 attrib = (uint32) un_nw_attrib(stb, 0, 0);
uint32 attrib = (voloptions & VOL_OPTION_IS_PIPE)
? (uint32) FILE_ATTR_SHARE
: (uint32) un_nw_attrib(stb, 0, 0);
U32_TO_32(attrib, p);
p += 4;
U16_TO_16((uint16)(attrib & 0xFFFF), p);
@ -953,7 +965,7 @@ static int get_add_new_entry(DIR_BASE_ENTRY *qbe, int namespace,
}
static int namespace_fn_match(uint8 *s, uint8 *p, int namespace)
/* for other namespaces than DOS + OS2 */
/* for *OTHER* namespaces than DOS + OS2 */
{
int pc, sc;
uint state = 0;
@ -1000,11 +1012,8 @@ static int namespace_fn_match(uint8 *s, uint8 *p, int namespace)
state = 1;
continue;
default : if ( pc != *s &&
( namespace != NAME_OS2
|| (!isalpha(pc)) || (!isalpha(*s))
|| (pc | 0x20) != (*s | 0x20) ) )
return(0);
default : if ( pc != *s )
return(0);
++s;
break;
@ -1048,7 +1057,6 @@ int nw_search_file_dir(int namespace, int datastream,
int len, uint8 *path, uint8 *info, int *perhaps_more)
{
static uint32 saved_sequence=0L;
#if 0
int max_counts = *count;
#endif
@ -1057,36 +1065,24 @@ static uint32 saved_sequence=0L;
*perhaps_more = 0;
*count = 0;
if (len > 255) return(-0x9c); /* wrong path */
if (result > -1) {
DIR_BASE_ENTRY *dbe=dir_base[result];
DIR_SEARCH_STRUCT *ds=(DIR_SEARCH_STRUCT*) xcmalloc(sizeof(DIR_SEARCH_STRUCT));
ds->unixname = (uint8*)nwpath_2_unix1(&(dbe->nwpath), 2, 258);
if (NULL != (ds->fdir = opendir(ds->unixname)) ) {
int lastsequence;
uint8 entry[257];
uint8 *pe=entry;
int have_wild=0;
int have_wild=0; /* do we have a wildcard entry */
int inode_search=0;
uint8 *is_ap=NULL; /* one after point */
struct dirent *dirbuff;
struct dirent *dirbuff=NULL;
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) {
saved_sequence=0L;
*sequence=0L;
}
#if 0
if (saved_sequence) {
seekdir(ds->fdir, saved_sequence);
saved_sequence=0L;
} else
#endif
if (*sequence)
seekdir(ds->fdir, *sequence);
dbe->locked++;
@ -1113,34 +1109,87 @@ static uint32 saved_sequence=0L;
if ( (namespace == NAME_DOS || namespace == NAME_OS2)
&& !(vol_options & VOL_OPTION_IGNCASE) ) {
if (vol_options & VOL_OPTION_DOWNSHIFT) {
downstr(entry);
down_fn(entry);
} else {
upstr(entry);
up_fn(entry);
}
}
XDPRINTF((5,0,"nw_s_f_d namsp=%d,sequence=%d, search='%s'",
XDPRINTF((5,0,"nw_s_f_d namsp=%d, sequence=%d, search='%s'",
namespace, *sequence, entry ));
while ((dirbuff = readdir(ds->fdir)) != (struct dirent*)NULL){
if (*sequence == MAX_U32)
*sequence=0L;
lastsequence=dbe->sequence;
if (!*sequence) {
if (have_wild)
dbe->sequence = 0;
dbe->dirpos = (off_t)0;
}
if (*sequence != dbe->sequence || dbe->dirpos < 1L) {
XDPRINTF((7, 0, "dirpos set to 0 dbe->sequence = %d, dirpos=%d",
dbe->sequence, dbe->dirpos));
dbe->dirpos = (off_t)0;
lastsequence = 0;
}
seekdir(ds->fdir, dbe->dirpos);
if ( ( (dirbuff=readdir(ds->fdir)) == NULL
|| dirbuff->d_ino != dbe->found_inode ) && dbe->found_inode) {
lastsequence = 0;
seekdir(ds->fdir, 0L);
XDPRINTF((7, 0, "dirbuff->d_ino %d != dbe->found_inode=%d ",
(dirbuff)?dirbuff->d_ino:0, dbe->found_inode));
dirbuff=NULL;
} else {
lastsequence++;
}
if (dbe->sequence != *sequence || !dbe->found_inode
|| dirbuff==NULL
|| dbe->found_inode != dirbuff->d_ino) {
XDPRINTF((7, 0, "needed new"));
while (lastsequence <= *sequence
&& (dirbuff=readdir(ds->fdir)) != NULL) {
lastsequence++;
if (dirbuff && dbe->found_inode
&& dirbuff->d_ino == dbe->found_inode
&& dbe->sequence == *sequence) /* perhaps dir shrunk */
break;
}
}
dbe->dirpos = telldir(ds->fdir);
while (dirbuff!=NULL) {
uint8 *name=(uint8*)(dirbuff->d_name);
if (dirbuff->d_ino && strlen((char*)name) < 256) {
int flag;
uint8 dname[256];
if (namespace == NAME_DOS || namespace == NAME_OS2) {
strcpy(dname, name);
unix2doscharset(dname);
} else
strcpy(dname, name);
XDPRINTF((5,0,"nw_search_file_dir Name='%s'", name));
if (!inode_search) {
if (namespace == NAME_DOS) {
flag = (*name != '.' && fn_dos_match(name, entry, vol_options));
flag = (*name != '.' && fn_dos_match(dname, entry, vol_options));
} else if (namespace == NAME_OS2) {
flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' ))
&& fn_os2_match(name, entry, vol_options);
&& fn_os2_match(dname, entry, vol_options);
} else {
flag = (!strcmp(name, entry)
|| namespace_fn_match(name, entry, namespace));
}
} else
flag = (dirbuff->d_ino == inode_search);
if (flag) {
strcpy(ds->kpath, name);
XDPRINTF((5,0,"nw_search_file_dir Name found=%s unixname=%s",
XDPRINTF((15,0,"nw_search_file_dir Name found=%s unixname=%s",
name, ds->unixname));
if (!stat(ds->unixname, &statb)) {
flag = (searchattrib & W_SEARCH_ATTR_ALL) == W_SEARCH_ATTR_ALL;
@ -1152,16 +1201,10 @@ static uint32 saved_sequence=0L;
}
if (flag) {
if (!found) {
strcpy(entry, name);
strcpy(entry, dname);
if ((dest_entry = get_add_new_entry(dbe, namespace, entry, 0)) > -1) {
found++;
#if 0
if (max_counts > 1) {
saved_sequence = (uint32)telldir(ds->fdir);
/* for next turn */
} else
#endif
break;
break;
} else {
XDPRINTF((1, 0, "nw_search_file_dir:Cannot add entry '%s'", entry));
}
@ -1180,35 +1223,46 @@ static uint32 saved_sequence=0L;
*(ds->kpath) = '\0';
}
} /* if */
} /* while */
dirbuff = readdir(ds->fdir);
lastsequence++;
} /* while */
*(ds->kpath) = '\0';
if (dest_entry > -1) {
DIR_BASE_ENTRY *dest_dbe=dir_base[dest_entry];
(void) nwp_stat(&(dest_dbe->nwpath), "nw_search_file_dir");
#if 0
if (saved_sequence)
*sequence= saved_sequence;
else
#endif
*sequence= (uint32)telldir(ds->fdir);
/* if (found < 2) saved_sequence=0L; */
result = build_dir_info(dest_dbe, datastream,
infomask |INFO_MSK_NAME_SPACE_INFO,
info);
*count=1;
#if 0
*perhaps_more=(found==2) ? 0xff : 0;
#else
*perhaps_more=(have_wild) ? 0xff : 0;
#endif
*sequence = lastsequence;
dbe->dirpos = telldir(ds->fdir);
if (have_wild) {
dbe->sequence = lastsequence;
dirbuff = readdir(ds->fdir);
if (dirbuff) {
*perhaps_more=0xff;
dbe->found_inode=dirbuff->d_ino;
} else {
dbe->found_inode=0;
*perhaps_more=0;
}
} else {
*perhaps_more=0;
}
XDPRINTF((5, 0, "more=%d, file=%s,next=%s",
*perhaps_more, dest_dbe->nwpath.path, dirbuff?dirbuff->d_name:""));
} else {
saved_sequence=0L;
result=-0xff; /* no files matching */
XDPRINTF((5, 0, "no files matching"));
}
dbe->locked=0;
closedir(ds->fdir);
} /* if NULL != ds->fdir */
} else { /* if NULL != ds->fdir */
result=-0xff; /* thanks Peter Gerhard :) */
XDPRINTF((5, 0, "could not opendir=`%s`", ds->unixname));
}
xfree(ds->unixname);
xfree(ds);
}

143
ncpserv.c
View File

@ -1,4 +1,4 @@
/* ncpserv.c 01-Nov-96 */
/* ncpserv.c 02-Jun-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -36,22 +36,29 @@ static int tells_server_version=1;
#endif
static int sock_nwbind=-1;
static int sock_echo =-1;
static int highest_fd = 10;
static int station_restrictions=0;
static int max_connections=MAX_CONNECTIONS;
static int get_ini(void)
static void set_highest_fd(int fd)
{
if (fd > highest_fd)
highest_fd=fd;
}
static int get_ini(int full)
{
FILE *f = open_nw_ini();
if (f){
uint8 buff[256];
int what;
while (0 != (what =get_ini_entry(f, 0, buff, sizeof(buff)))) {
#if 0
if (6 == what) { /* Server Version */
tells_server_version = atoi((char*)buff);
} else
#endif
if (400 == what) { /* station file */
if (60 == what && full) { /* max_connections */
max_connections=atoi((char*)buff);
if (max_connections < 5)
max_connections=MAX_CONNECTIONS;
} else if (400 == what) { /* station file */
new_str(station_fn, buff);
} else if (402 == what) { /* station connect restrictions */
station_restrictions=atoi((char*)buff);
@ -139,28 +146,37 @@ typedef struct {
time_t last_access; /* time of last 0x2222 request */
} CONNECTION;
static CONNECTION connections[MAX_CONNECTIONS];
static int anz_connect=0; /* actual count connections */
static CONNECTION *connections=NULL;
static int count_connections=0; /* actual count connections */
#define L_MAX_CONNECTIONS MAX_CONNECTIONS
#define TEST_HIGH_CONN 0
static int new_conn_nr(void)
{
int j = -1;
if (!anz_connect){ /* init all */
j = L_MAX_CONNECTIONS;
if (!count_connections){ /* init all */
j = max_connections;
while (j--) {
connections[j].fd = -1;
connections[j].pid = -1;
}
anz_connect++;
count_connections++;
#if TEST_HIGH_CONN
return(count_connections=301); /* TESTS ONLY */
#endif
return(1);
}
j = -1;
while (++j < L_MAX_CONNECTIONS) {
#if TEST_HIGH_CONN
j=300-1; /* TESTS ONLY */
#endif
while (++j < max_connections) {
CONNECTION *c=&(connections[j]);
if (c->fd < 0 && c->pid < 0) {
if (++j > anz_connect) anz_connect=j;
if (++j > count_connections) count_connections=j;
return(j);
}
}
@ -171,7 +187,7 @@ static int new_conn_nr(void)
static int free_conn_nr(int nr)
{
if (nr && --nr < anz_connect) {
if (nr && --nr < count_connections) {
connections[nr].fd = -1;
connections[nr].pid = -1;
return(0);
@ -182,7 +198,7 @@ static int free_conn_nr(int nr)
static int find_conn_nr(ipxAddr_t *addr)
{
int j = -1;
while (++j < anz_connect) {
while (++j < count_connections) {
if (connections[j].fd > -1 &&
!memcmp((char*)&(connections[j].client_adr),
(char*)addr, sizeof(ipxAddr_t))) return(++j);
@ -193,7 +209,7 @@ static int find_conn_nr(ipxAddr_t *addr)
static void clear_connection(int conn)
{
nwserv_close_conn(conn);
if (conn > 0 && --conn < anz_connect) {
if (conn > 0 && --conn < count_connections) {
CONNECTION *c = &connections[conn];
if (c->fd > -1) {
#if !CALL_NWCONN_OVER_SOCKET
@ -212,12 +228,12 @@ static void kill_connections(void)
int stat_loc;
int pid;
while ((pid=waitpid(-1, &stat_loc, WNOHANG)) > 0) {
conn = anz_connect;
conn = count_connections;
while (conn--) {
if (connections[conn].pid == pid) clear_connection(conn+1);
}
}
conn = anz_connect;
conn = count_connections;
while (conn--) {
CONNECTION *c = &connections[conn];
if (c->fd < 0 && c->pid > -1) {
@ -225,10 +241,10 @@ static void kill_connections(void)
c->pid = -1;
}
}
conn = anz_connect;
conn = count_connections;
while (conn--) {
CONNECTION *c = &connections[conn];
if (c->fd < 0 && c->pid < 0) anz_connect--;
if (c->fd < 0 && c->pid < 0) count_connections--;
else break;
}
}
@ -243,8 +259,13 @@ static int find_get_conn_nr(ipxAddr_t *addr)
#if !CALL_NWCONN_OVER_SOCKET
int fds[2];
int res=pipe(fds);
memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t));
if (pipe(fds) < 0) {
if (res > -1) {
set_highest_fd(fds[0]);
set_highest_fd(fds[1]);
}
if (res < 0) {
errorp(0, "find_get_conn_nr, pipe", NULL);
free_conn_nr(connection);
return(0);
@ -264,6 +285,8 @@ static int find_get_conn_nr(ipxAddr_t *addr)
if (nw_debug) t_error("t_bind !OK");
t_close(ipx_fd);
ipx_fd = -1;
} else {
set_highest_fd(ipx_fd);
}
} else {
if (nw_debug) t_error("t_open !Ok");
@ -292,12 +315,11 @@ static int find_get_conn_nr(ipxAddr_t *addr)
/* new process */
char *progname="nwconn";
char pathname[300];
char pidstr[20];
char pidstr[20];
char connstr[20];
char addrstr[100];
char nwbindsock[20];
char echosock[20];
char divstr[50];
int l;
int j = 3;
#if !CALL_NWCONN_OVER_SOCKET
close(fds[1]); /* no writing */
@ -309,15 +331,21 @@ static int find_get_conn_nr(ipxAddr_t *addr)
#endif
dup2(ncp_fd, 3); /* becomes 3 */
while (j++ < 100) close(j); /* close all > 3 */
while (j++ < highest_fd) close(j); /* close all > 3 */
sprintf(pidstr, "%d", akt_pid);
sprintf(connstr, "%d", connection);
ipx_addr_to_adr(addrstr, addr);
sprintf(nwbindsock, "%04x", sock_nwbind);
sprintf(echosock, "%04x", sock_echo);
l=sprintf(divstr, "()INIT-:%08x,%04x,%04x-",
akt_pid, sock_nwbind, sock_echo);
if (l < 48) {
memset(divstr+l, '-', 48-l);
*(divstr+48)='\0';
}
execl(get_exec_path(pathname, progname), progname,
pidstr, addrstr, connstr, nwbindsock, echosock, NULL);
connstr, addrstr, divstr, NULL);
exit(1); /* normaly not reached */
}
@ -373,7 +401,7 @@ static void ncp_response(int type, int sequence,
ncpresponse->sequence = (uint8) sequence;
ncpresponse->connection = (uint8) connection;
ncpresponse->task = (uint8) task;
ncpresponse->reserved = 0;
ncpresponse->high_connection= (connection >> 8) & 0xff;
ncpresponse->completition = (uint8)completition;
ncpresponse->connect_status = (uint8)connect_status;
if (nw_debug){
@ -392,7 +420,7 @@ static void ncp_response(int type, int sequence,
static void close_all(void)
{
int k=0;
while (k++ < anz_connect) clear_connection(k);
while (k++ < count_connections) clear_connection(k);
if (ncp_fd > -1) {
t_unbind(ncp_fd);
t_close(ncp_fd);
@ -468,7 +496,7 @@ static int handle_ctrl(void)
case 0xeeee:
get_ini_debug(NCPSERV);
get_ini();
get_ini(0);
break;
case 0xffff : /* server down */
@ -497,15 +525,16 @@ static void handle_ncp_request(void)
XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr)));
if ((type = GET_BE16(ncprequest->type)) == 0x2222
|| type == 0x5555) {
int connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
int connection = (int)ncprequest->connection;
XDPRINTF((10,0, "GOT 0x%x in NCPSERV connection=%d", type, connection));
#if 0
ncp_response(0x9999, ncprequest->sequence,
connection, ncprequest->task,
0x0, 0, 0);
#endif
if ( connection > 0 && connection <= anz_connect) {
if ( connection > 0 && connection <= count_connections) {
CONNECTION *c = &(connections[connection-1]);
if (!memcmp(&from_addr, &(c->client_adr), sizeof(ipxAddr_t))) {
@ -565,13 +594,14 @@ static void handle_ncp_request(void)
type,
visable_ipx_adr(&from_addr),
c->fd,
ncprequest->connection,
anz_connect));
(int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8),
count_connections));
} else {
/* here the connection number is wrong */
XDPRINTF((1,0, "Not ok:0x%x conn=%d of %d conns",
type, ncprequest->connection,
anz_connect));
count_connections));
}
if (type == 0x5555 || (type == 0x2222 && ncprequest->function == 0x19)) {
@ -582,20 +612,35 @@ static void handle_ncp_request(void)
cstat = 1;
}
ncp_response(0x3333, ncprequest->sequence,
ncprequest->connection,
(int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8),
(type== 0x5555) ? 0 : ncprequest->task, /* task */
compl, /* completition */
cstat, /* conn status */
0);
0);
#if ENABLE_BURSTMODE
} else if (type == 0x7777) { /* BURST-mode */
int connection = (int) GET_16(((BURSTPACKET*)ncprequest)->dest_conn);
if ( connection > 0 && connection <= count_connections) {
CONNECTION *c = &(connections[connection-1]);
#if CALL_NWCONN_OVER_SOCKET
send_to_nwconn(c->fd, (char*)ncprequest, in_len);
#else
write(c->fd, (char*)ncprequest, in_len);
#endif
}
#endif
#if !CALL_NWCONN_OVER_SOCKET
/* here comes a call from nwbind */
} else if (type == 0x3333
&& IPXCMPNODE(from_addr.node, my_addr.node)
&& IPXCMPNET (from_addr.net, my_addr.net)) {
int connection = (int)ncprequest->connection;
int connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
XDPRINTF((6,0, "GOT 0x3333 in NCPSERV connection=%d", connection));
if ( connection > 0 && connection <= anz_connect) {
if ( connection > 0 && connection <= count_connections) {
CONNECTION *c = &(connections[connection-1]);
if (c->fd > -1) write(c->fd, (char*)ncprequest, in_len);
}
@ -643,12 +688,14 @@ static void handle_ncp_request(void)
#ifdef _MAR_TESTS_xx
} else if (type == 0xc000) {
/* rprinter */
int connection = (int)ncprequest->connection;
int connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
int sequence = (int)ncprequest->sequence;
ncp_response(0x3333, sequence, connection, 1, 0x0, 0, 0);
#endif
} else {
int connection = (int)ncprequest->connection;
int connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
int sequence = (int)ncprequest->sequence;
XDPRINTF((1,0, "Got UNKNOWN TYPE: 0x%x", type));
ncp_response(0x3333, sequence, connection, 1, 0xfb, 0, 0);
@ -663,7 +710,8 @@ int main(int argc, char *argv[])
errorp(1, "Usage:", "%s: nwname address nwbindsock echosocket", argv[0]);
return(1);
}
get_ini();
get_ini(1);
connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION));
strncpy(my_nwname, argv[1], 48);
my_nwname[47] = '\0';
adr_to_ipx_addr(&my_addr, argv[2]);
@ -705,6 +753,7 @@ int main(int argc, char *argv[])
}
}
close_all();
xfree(connections);
return(0);
}

54
net.h
View File

@ -1,4 +1,4 @@
/* net.h 25-Oct-96 */
/* net.h 02-Jun-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
@ -66,6 +66,10 @@ extern int errno;
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef LINUX
# define inline /**/
#endif
#ifdef SPARC
# define U16_TO_BE16 X_U16_TO_16
# define U32_TO_BE32 X_U32_TO_32
@ -217,23 +221,6 @@ extern int errno;
# define MAX_DIR_BASE_ENTRIES 10
#endif
#ifndef MAX_NW_ROUTES
# define MAX_NW_ROUTES 50
#endif
#ifndef MAX_RIP_ENTRIES
# define MAX_RIP_ENTRIES 50
#endif
#if MAX_RIP_ENTRIES < 50
# undef MAX_RIP_ENTRIES
# define MAX_RIP_ENTRIES 50
#endif
#ifndef MAX_NW_SERVERS
# define MAX_NW_SERVERS MAX_NW_ROUTES
#endif
#ifndef HANDLE_ALL_SAP_TYPS
# define HANDLE_ALL_SAP_TYPS 0
#endif
@ -254,6 +241,14 @@ extern int errno;
# define RW_BUFFERSIZE 512
#endif
#ifndef ENABLE_BURSTMODE
# define ENABLE_BURSTMODE 0 /* no Burst mode by default */
#endif
#ifndef PERSISTENT_SYMLINKS
# define PERSISTENT_SYMLINKS 0
#endif
#ifndef SOCK_EXTERN
# define SOCK_EXTERN 0 /* no external SOCKET */
#endif
@ -373,7 +368,7 @@ typedef union {
uint8 sequence;
uint8 connection; /* low connection */
uint8 task;
uint8 reserved; /* high connection */
uint8 high_connection; /* high connection */
uint8 completition; /* bzw. ERROR CODE */
uint8 connect_status;
} ncpresponse;
@ -382,9 +377,27 @@ typedef union {
uint8 sequence;
uint8 connection; /* low connection */
uint8 task;
uint8 reserved; /* high connection */
uint8 high_connection; /* high connection */
uint8 function; /* Function */
} ncprequest;
struct S_BURSTPACKET { /* size = 36 */
uint8 type[2]; /* 0x7777 */
uint8 flags; /* 0x10 = EOB (EndOfBurst) */
/* 0x80 = SYS (Systemflag) */
uint8 streamtyp; /* 2 = BIG_SEND_BURST stream typ */
uint8 source_conn[4];
uint8 dest_conn[4];
uint8 packet_sequence[4]; /* hi-lo, incr. by every packet */
uint8 delaytime[4]; /* hi-lo, statistik */
uint8 burst_seq[2]; /* akt_sequence ? */
uint8 ack_seq[2]; /* next_sequnce ? */
uint8 burstsize[4]; /* hi-lo, complete burstsize */
uint8 burstoffset[4]; /* hi-lo */
uint8 datasize[2]; /* hi-lo, number of data byte's in this packet */
uint8 missing[2]; /* 0,0 , number of missing fragments, follows */
} burstpacket;
struct S_OWN_DATA {
struct {
uint8 type[2]; /* 0xeeee */
@ -415,6 +428,7 @@ typedef struct S_CONFREQ CONFREQ;
typedef struct S_DIAGRESP DIAGRESP;
typedef struct S_NCPRESPONSE NCPRESPONSE;
typedef struct S_NCPREQUEST NCPREQUEST;
typedef struct S_BURSTPACKET BURSTPACKET;
typedef struct S_OWN_DATA OWN_DATA;
typedef struct S_OWN_REPLY OWN_REPLY;

View File

@ -1,5 +1,5 @@
/* nwbind.c */
#define REVISION_DATE "20-Apr-97"
#define REVISION_DATE "07-Jul-97"
/* NCP Bindery SUB-SERVER */
/* authentification and some message handling */
@ -76,7 +76,9 @@ typedef struct {
int pid_nwconn; /* pid of user process nwconn */
} CONNECTION;
static CONNECTION connections[MAX_CONNECTIONS];
static int max_nw_vols=MAX_NW_VOLS;
static int max_connections=MAX_CONNECTIONS;
static CONNECTION *connections=NULL;
static CONNECTION *act_c=(CONNECTION*)NULL;
static int act_connection;
static int internal_act=0;
@ -145,7 +147,7 @@ static void sent_down_message(void)
{
int k = -1;
server_goes_down++;
while (++k < MAX_CONNECTIONS) {
while (++k < max_connections) {
CONNECTION *cn=&connections[k];
if (cn->active) {
strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58);
@ -156,7 +158,7 @@ static void sent_down_message(void)
static void open_clear_connection(int conn, int activate, uint8 *addr)
{
if (conn > 0 && --conn < MAX_CONNECTIONS) {
if (conn > 0 && --conn < max_connections) {
CONNECTION *c = &connections[conn];
c->active = activate;
c->message[0] = '\0';
@ -254,7 +256,7 @@ static void handle_fxx(int gelen, int func)
int connr = (int) (*conns++);
int result = 0xff; /* target not ok */
CONNECTION *cn;
if (connr > 0 && --connr < MAX_CONNECTIONS
if (connr > 0 && --connr < max_connections
&& ((cn = &connections[connr]))->active ) {
if (!cn->message[0]) {
strmaxcpy(cn->message, msg, min(58, msglen));
@ -391,16 +393,16 @@ static void handle_fxx(int gelen, int func)
i=0;
h=0;
for (k=0; k < MAX_CONNECTIONS; k++) {
for (k=0; k < max_connections; k++) {
if (connections[k].active) {
i++;
h = k+1;
}
}
U16_TO_BE16(i, xdata->connection_in_use);
U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections);
U16_TO_BE16(max_connections, xdata->maxconnections);
U16_TO_BE16(h, xdata->peak_connection);
U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes);
U16_TO_BE16(max_nw_vols, xdata->max_volumes);
xdata->security_level=1;
/*
* if this level is 0
@ -427,9 +429,9 @@ static void handle_fxx(int gelen, int func)
uint8 appl_number[2];
} *xdata = (struct XDATA*) responsedata;
/* serial-number 4-Byte */
U32_TO_BE32(NETWORK_SERIAL_NMBR, xdata->serial_number);
/* applikation-number 2-Byte */
U16_TO_BE16(NETWORK_APPL_NMBR, xdata->appl_number);
U32_TO_BE32(network_serial_nmbr, xdata->serial_number);
/* application-number 2-Byte */
U16_TO_BE16(network_appl_nmbr, xdata->appl_number);
data_len = sizeof(struct XDATA);
}
break;
@ -437,9 +439,11 @@ static void handle_fxx(int gelen, int func)
case 0x13 : /* Get Connection Internet Address, old */
case 0x1a : { /* Get Connection Internet Address, new */
int conn = (ufunc == 0x13)
? (int) *rdata
: GET_32(rdata);
if (conn && --conn < MAX_CONNECTIONS
? ((max_connections < 256)
? (int) *rdata
: act_connection)
: GET_32(rdata);
if (conn && --conn < max_connections
&& connections[conn].active ) {
CONNECTION *cx=&(connections[conn]);
data_len = sizeof(ipxAddr_t);
@ -505,7 +509,7 @@ static void handle_fxx(int gelen, int func)
int k=-1;
int anz = 0;
p = responsedata+1;
while (++k < MAX_CONNECTIONS && anz < 255) {
while (++k < max_connections && anz < 255) {
CONNECTION *cn= &connections[k];
if (cn->active && cn->object_id == obj.id) {
*p++=(uint8)k+1;
@ -518,8 +522,8 @@ static void handle_fxx(int gelen, int func)
}
break;
case 0x16 : /* Get Connection Info, old */
case 0x1c : { /* Get Connection Info, new */
case 0x16 : /* Get Connection Info, old */
case 0x1c : { /* Get Connection Info, new ( > 255 connections) */
struct XDATA {
uint8 object_id[4];
uint8 object_type[2];
@ -527,14 +531,15 @@ static void handle_fxx(int gelen, int func)
uint8 login_time[7];
uint8 reserved;
} *xdata = (struct XDATA*) responsedata;
int conn = (ufunc == 0x16)
? (int) *rdata
: GET_32(rdata);
int conn = (ufunc == 0x16)
? ((max_connections < 256)
? (int) *rdata
: act_connection)
: GET_32(rdata);
memset(xdata, 0, sizeof(struct XDATA));
data_len = sizeof(struct XDATA);
if (conn && conn <= MAX_CONNECTIONS
&& connections[conn-1].active ) {
if (conn && conn <= max_connections
&& connections[conn-1].active ) {
CONNECTION *cx=&(connections[conn-1]);
NETOBJ obj;
int result;
@ -547,7 +552,7 @@ static void handle_fxx(int gelen, int func)
strncpy(xdata->object_name, obj.name, 48);
get_login_time(xdata->login_time, cx);
} /* else completition = (uint8)(-result); */
} else if (!conn || conn > MAX_CONNECTIONS) {
} else if (!conn || conn > max_connections) {
data_len = 0;
completition = 0xfd;
}
@ -1147,13 +1152,22 @@ static void handle_fxx(int gelen, int func)
}
break;
case 0x7d : { /* Read Queue Current Status, new */
NETOBJ obj;
struct XDATA {
uint8 id[4]; /* queue id */
uint8 status[4]; /* &1 no station allowed */
/* &2 no other queue server allowed */
/* &4 no queue server allowed get entries */
uint8 entries[4]; /* current entries */
uint8 servers[4]; /* current servers */
} *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata);
XDPRINTF((1, 0, "TODO:READ QUEUE STATUS NEW of Q=0x%lx", obj.id));
completition=0xd5; /* no Queue Job */
}break;
memset(xdata, 0, sizeof(*xdata));
U32_TO_BE32(obj.id, xdata->id);
data_len=sizeof(struct XDATA);
} break;
case 0x81 : { /* Get Queue Job List */
NETOBJ obj;
@ -1219,10 +1233,10 @@ static void handle_fxx(int gelen, int func)
if (anz_conns) {
while (++k < anz_conns) {
int conn= (int) *co++;
if (conn == ncprequest->connection) {
if (conn == act_connection) {
strmaxcpy(act_c->message, msg, min(58, msglen));
connect_status = 0x40; /* don't know why */
} else if (conn && --conn < MAX_CONNECTIONS) {
} else if (conn && --conn < max_connections) {
CONNECTION *cc= &(connections[conn]);
if (cc->object_id) { /* if logged */
strmaxcpy(cc->message, msg, min(58, msglen));
@ -1262,7 +1276,7 @@ static void handle_fxx(int gelen, int func)
ncpresponse->sequence = ncprequest->sequence;
ncpresponse->task = ncprequest->task;
ncpresponse->connection = ncprequest->connection;
ncpresponse->reserved = 0;
ncpresponse->high_connection= ncprequest->high_connection;
ncpresponse->completition = completition;
if (act_c->message[0]) connect_status |= 0x40;
@ -1426,8 +1440,6 @@ int main(int argc, char *argv[])
init_tools(NWBIND, 0);
memset(connections, 0, sizeof(connections));
strmaxcpy(my_nwname, argv[1], 47);
adr_to_ipx_addr(&my_addr, argv[2]);
@ -1439,6 +1451,13 @@ int main(int argc, char *argv[])
exit(1);
}
internal_act = 0;
max_connections=get_ini_int(60); /* max_connections */
if (max_connections < 5)
max_connections=MAX_CONNECTIONS;
connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION));
max_nw_vols=get_ini_int(61); /* max. volumes */
if (max_nw_vols < 1)
max_nw_vols = MAX_NW_VOLS;
#ifdef LINUX
set_emu_tli();
@ -1470,16 +1489,18 @@ int main(int argc, char *argv[])
XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr)));
if ( ncprequest->type[0] == 0x22
&& ncprequest->type[1] == 0x22) {
act_connection = ((int)ncprequest->connection);
if (act_connection > 0 && act_connection <= MAX_CONNECTIONS) {
act_connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
if (act_connection > 0 && act_connection <= max_connections) {
act_c = &(connections[act_connection-1]);
internal_act = 0;
if (act_c->active && IPXCMPNODE(from_addr.node, my_addr.node)
&& IPXCMPNET (from_addr.net, my_addr.net)) {
handle_fxx(ud.udata.len, (int)ncprequest->function);
} else {
XDPRINTF((1, 0, "NWBIND-LOOP addr of connection=%d is wrong",
act_connection));
XDPRINTF((1, 0, "NWBIND-LOOP addr=%s of connection=%d is wrong",
visable_ipx_adr(&from_addr), act_connection));
}
} else {
XDPRINTF((1, 0, "NWBIND-LOOP connection=%d is wrong",
@ -1513,5 +1534,6 @@ int main(int argc, char *argv[])
}
}
sync_dbm();
xfree(connections);
return(0);
}

View File

@ -73,7 +73,7 @@ static uint8 *requestdata=((uint8*)&ipxdata_out)+sizeof(NCPREQUEST);
static void ncp_request(int type, int sequence,
int connection, int task,
int reserved, int function,
int function,
int data_len, char *komment)
{
@ -81,12 +81,12 @@ static void ncp_request(int type, int sequence,
ncprequest->sequence = (uint8) sequence;
ncprequest->connection = (uint8) connection;
ncprequest->task = (uint8) task;
ncprequest->reserved = (uint8) reserved;
ncprequest->high_connection= (uint8) (connection>>8);
ncprequest->function = (uint8) function;
{
int j = data_len;
XDPRINTF((1, 0, "NCP REQUEST: type:0x%x, seq:%d, conn:%d, task:%d, reserved:0x%x, func:0x%x",
type, sequence, connection, task, reserved, function));
XDPRINTF((1, 0, "NCP REQUEST: type:0x%x, seq:%d, conn:%d, task:%d, func:0x%x",
type, sequence, connection, task, function));
if (j > 0){
uint8 *p=requestdata;
XDPRINTF((1, 2, "len %d, DATA:", j));
@ -152,16 +152,16 @@ static int handle_event(void)
int j = responselen;
int sequence = (int)ncpresponse->sequence;
int connection = (int)ncpresponse->connection;
int connection = (int)ncpresponse->connection
| (( (int)ncpresponse->high_connection) <<8);
int task = (int)ncpresponse->task;
int reserved = (int)ncpresponse->reserved;
int completition = (int)ncpresponse->completition;
int connect_status = (int)ncpresponse->connect_status;
int type = GET_BE16(ncpresponse->type);
XDPRINTF((1,0, "Ptyp:%d von: %s, len=%d", (int)ipx_pack_typ, visable_ipx_adr(&source_adr), responselen));
XDPRINTF((1,0, "RESPONSE:t:0x%x, seq:%d, conn:%d, task:%d, res:0x%x, complet.:0x%x, connect:0x%x",
type, sequence, connection, task, reserved, completition, connect_status));
XDPRINTF((1,0, "RESPONSE:t:0x%x, seq:%d, conn:%d, task:%d, complet.:0x%x, connect:0x%x",
type, sequence, connection, task, completition, connect_status));
if (j > 0){
uint8 *p=responsedata;
@ -187,25 +187,26 @@ static int connection=0;
#define RDATA(xdata, xfunc, xcomment) \
memcpy(requestdata, (xdata), sizeof(xdata)); \
ncp_request(0x2222, sequence, connection, 1, 0, \
ncp_request(0x2222, sequence, connection, 1, \
(xfunc), sizeof(xdata), (xcomment))
#define ODATA(xfunc, xcomment) \
ncp_request(0x2222, sequence, connection, 1, 0, \
ncp_request(0x2222, sequence, connection, 1, \
(xfunc), 0, (xcomment))
#define VDATA(xfunc, xsize, xcomment) \
ncp_request(0x2222, sequence, connection, 1, 0, \
ncp_request(0x2222, sequence, connection, 1, \
(xfunc), (xsize), (xcomment))
static int get_conn_nr(void)
{
ncp_request(0x1111, sequence, 2, 2, 0xff, 0,
ncp_request(0x1111, sequence, 0xff02, 2, 0,
0, "Get Connection Nr.");
if (!handle_event()) {
connection = ncpresponse->connection;
connection = (int)ncpresponse->connection
| (((int)ncpresponse->high_connection)<<8);
XDPRINTF((1, 0, "NWCLIENT GOT CONNECTION NR:%d", connection));
return(0);
}

475
nwconn.c
View File

@ -1,4 +1,4 @@
/* nwconn.c 16-Apr-97 */
/* nwconn.c 22-Jun-97 */
/* one process / connection */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -30,6 +30,10 @@
#include "connect.h"
#include "nwqueue.h"
#include "namspace.h"
#include "nwconn.h"
IPX_IO_RW ipx_io;
int use_ipx_io=0;
int act_connection = 0;
int act_pid = 0;
@ -59,21 +63,64 @@ static uint8 *requestdata = readbuff + sizeof(NCPREQUEST);
static int ncp_type;
static int sock_nwbind=-1;
static int sock_echo =-1;
static char *prog_title;
static int req_printed=0;
typedef struct {
BURSTPACKET *sendburst; /* buffer for sending burstpacket
* allocated and prefilled by response to
* func 0x65
* max. max_packet_size
*/
uint8 *send_buf; /* we look from servers side
* complete data buf of burst reply
* file read status + file read buf
*/
int max_send_size; /* send_buf size, complete Burst DATA size */
uint32 packet_sequence; /* -> packet_sequence
* will be increased after every
* packet
*/
int burst_sequence;
struct t_unitdata ud;
ipxAddr_t to_addr;
uint8 *recv_buf; /* complete data buf for burst read requests */
int max_recv_size; /* allocated size of recv_buf */
int max_burst_data_size; /* size of BURSTDATA, max. IPX_DATA - BURSTHEADER */
uint8 ipx_pack_typ;
} BURST_W;
static BURST_W *burst_w=NULL;
static void set_program_title(char *s)
{
memset(prog_title, 0, 49);
if (s&&*s)
strmaxcpy(prog_title, s, 48);
else
strcpy(prog_title, "()");
}
static int ncp_response(int sequence, int task,
int completition, int data_len)
{
ncpresponse->sequence = (uint8) sequence;
ncpresponse->task = (uint8) task;
ncpresponse->completition = (uint8) completition;
ncpresponse->reserved = (uint8) 0;
last_sequence = sequence;
if (req_printed) {
XDPRINTF((0,0, "NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x task=%d TO %s",
(int)ncpresponse->sequence, (int) ncpresponse->connection, (int)completition,
(int)ncpresponse->sequence,
(int)ncpresponse->connection
| (((int)ncpresponse->high_connection) << 8),
(int)completition,
(int)ncpresponse->task, visable_ipx_adr((ipxAddr_t *) ud.addr.buf)));
}
ud.udata.len = ud.udata.maxlen = sizeof(NCPRESPONSE) + data_len;
@ -114,16 +161,15 @@ static void pr_debug_request()
case 0x57 : ufunc = (int) *(requestdata); break;
default : break;
} /* switch */
XDPRINTF((0, 0, "NCP REQUEST: func=0x%02x, ufunc=0x%02x, seq:%03d, task:%02d",
XDPRINTF((1, 0, "NCP REQUEST: func=0x%02x, ufunc=0x%02x, seq:%03d, task:%02d",
(int)ncprequest->function, ufunc,
(int)ncprequest->sequence,
(int)ncprequest->task));
} else {
XDPRINTF((0, 0, "Got NCP:type:0x%x, seq:%d, task:%d, reserved:0x%x, func=0x%x",
XDPRINTF((1, 0, "Got NCP:type:0x%x, seq:%d, task:%d, func=0x%x",
ncp_type,
(int)ncprequest->sequence,
(int)ncprequest->task,
(int)ncprequest->reserved,
(int)ncprequest->function));
}
if (requestlen > 0){
@ -138,8 +184,9 @@ static void pr_debug_request()
XDPRINTF((0,1,NULL));
}
}
#if TEST_FNAME
static int test_handle = -1;
#endif
static int handle_ncp_serv(void)
{
int function = (int)ncprequest->function;
@ -171,6 +218,34 @@ static int handle_ncp_serv(void)
if (ncp_type == 0x2222) {
switch (function) {
#if 0
case 0x3 : { /* Log File */
NWCONN 1:UNKNOWN FUNCTION od. TYPE: 0x3
NWCONN 1:NWCONN NCP_RESP seq:56, conn:1, compl=0xfb task=5 TO
net=0:0:0:22, node=0:0:1:22:59:52, sock=40:03
NWCONN 1:NCP REQUEST: func=0x03, ufunc=0x00, seq:060, task:05
NWCONN 1:len 15, DATA:,0x5,0x1,0x0,0x12,0xa,'0','9','0','6',
'9','7','.','Z','I','P'
;;
} break;
case 0x4 : { /* Lock File Set */
;;
} break;
case 0x5 : { /* Release File */
;;
} break;
case 0x6 : { /* Release File Set */
;;
} break;
case 0x7 : { /* Clear File */
;;
} break;
case 0x8 : { /* Clear File Set */
;;
} break;
#endif
case 0x12 : { /* Get Volume Info with Number */
int volume = (int)*requestdata;
struct XDATA {
@ -865,6 +940,7 @@ static int handle_ncp_serv(void)
set_default_guid();
nw_setup_home_vol(-1, NULL);
set_act_obj_id(0); /* NOT logged in */
set_program_title(NULL);
return(-1); /* nwbind must do a little rest */
break;
@ -878,11 +954,11 @@ static int handle_ncp_serv(void)
uint8 fhandle[4]; /* Filehandle */
uint8 offset[4];
uint8 size[4];
uint8 weisnicht[2]; /* lock timeout ??? */
uint8 unknown[2]; /* lock timeout ??? */
} *input = (struct INPUT *)ncprequest;
int fhandle = GET_32 (input->fhandle);
int offset = GET_BE32(input->offset);
int size = GET_BE32(input->size);
uint32 offset= GET_BE32(input->offset);
uint32 size = GET_BE32(input->size);
completition = (uint8)(-nw_lock_file(fhandle,
offset, size,
(int)(function == 0x1a)));
@ -1074,23 +1150,6 @@ static int handle_ncp_serv(void)
uint32 fhandle = GET_32(input->fhandle);
completition = (uint8)(-nw_close_file(fhandle, 0));
#if 0
#ifdef SIOCIPXNCPCONN
{
struct {
int fh;
int fd;
int mode;
} ncp_1;
ncp_1.fh = 0;
ncp_1.fd = -1;
ncp_1.mode = 0;
ioctl(0, SIOCIPXNCPCONN+1, &ncp_1);
}
#endif
#endif
#if TEST_FNAME
if (!completition && fhandle == test_handle) {
do_druck++;
@ -1211,7 +1270,7 @@ static int handle_ncp_serv(void)
uint8 size[4]; /* Position ??? */
} *xdata=(struct XDATA*)responsedata;
int fhandle = GET_32(input->fhandle);
int size = nw_seek_datei(fhandle, 0);
int size = nw_seek_file(fhandle, 0);
if (size > -1) {
data_len = sizeof(struct XDATA);
U32_TO_BE32(size, xdata->size);
@ -1244,28 +1303,13 @@ static int handle_ncp_serv(void)
max_size, rw_buffer_size));
size = -0x88; /* we say wrong filehandle */
} else
size = nw_read_datei(fhandle,
size = nw_read_file(fhandle,
xdata->data+zusatz,
max_size,
offset);
if (size > -1) {
U16_TO_BE16(size, xdata->size);
data_len=size+zusatz+2;
#if 0
#ifdef SIOCIPXNCPCONN
{
struct {
int fh;
int fd;
int mode;
} ncp_1;
ncp_1.fh = fhandle;
ncp_1.fd = get_nwfd(fhandle);
ncp_1.mode = 0;
ioctl(0, SIOCIPXNCPCONN+1, &ncp_1);
}
#endif
#endif
} else completition = (uint8) -size;
}
break;
@ -1283,12 +1327,14 @@ static int handle_ncp_serv(void)
off_t offset = GET_BE32(input->offset);
int fhandle = GET_32 (input->fhandle);
int input_size = GET_BE16(input->size);
int size = nw_write_datei(fhandle,
int size = nw_write_file(fhandle,
input->data,
input_size,
offset);
if (size < 0)
completition = (uint8) -size;
else if (size < input_size)
completition = (uint8)0xff;
}
break;
@ -1418,58 +1464,135 @@ static int handle_ncp_serv(void)
#endif
#if 0
case 0x61 : { /* Negotiate Buffer Size, Packetsize new ? */
/* > 3.11 */
case 0x61 :
#if ENABLE_BURSTMODE
if (tells_server_version > 1) { /* > 3.11 */
/* Negotiate Buffer Size, Packetsize new ? */
int wantsize = GET_BE16((uint8*)requestdata);
/* wantsize is here max.
* phys. packet size without MAC-header
* e.g. 1500 if ethernet
*/
int flags = (int) *(requestdata+2);
/* wantsize is here normally 1500 */
/**** flags ***********************
* CHECKSUMMING_REQUESTED 1
* SIGNATURE_REQUESTED 2
* COMPLETE_SIGNATURES_REQUESTED 4
* ENCRYPTION_REQUESTED 8
* LIP_DISABLED 0x80
**********************************/
struct XDATA {
uint8 getsize[2];
uint8 socket[2]; /* echo socket */
uint8 flags; /* zero */
} *xdata= (struct XDATA*)responsedata;
memset(xdata, 0, sizeof(*xdata));
wantsize = min(1500, wantsize);
wantsize = min(IPX_MAX_DATA+30, wantsize);
rw_buffer_size = min(RW_BUFFERSIZE, wantsize-64);
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), flags=0x%x",
(int) wantsize, (int) wantsize, flags));
} else
#endif
{
XDPRINTF((2,0, "Function '0x61' (Burst) not enabled"));
completition = 0xfb; /* unknown request */
nw_debug=0;
}
break;
#else
case 0x61 : /* Negotiate Buffer Size, Packetsize new ? */
XDPRINTF((2,0, "Function '0x61' not supportet"));
completition = 0xfb; /* unknown request */
nw_debug=0;
break;
#endif
#if 0
case 0x65 : /* Packet Burst Connection Request */
#if ENABLE_BURSTMODE
if (tells_server_version > 1) { /* > 3.11 */
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 */
uint8 header[7]; /* Requestheader */
uint8 connid[4]; /* RANDOM ID */
/* build by time() */
uint8 max_packet_size[4]; /* HI-LO */
/* max_packet_size is here max.
* phys. packet size without MAC-header
* e.g. 1500 if ethernet
*/
uint8 target_socket[2]; /* HI-LO */
uint8 max_send_size[4]; /* HI-LO */
uint8 max_recv_size[4]; /* HI-LO */
} *input = (struct INPUT *)ncprequest;
struct XDATA {
uint8 result;
uint8 target_id[4];
uint8 max_packet_size[4];
uint8 server_id[4]; /* RANDOM ID */
/* build by time() */
uint8 max_packet_size[4]; /* HI-LO */
uint8 max_send_size[4]; /* HI-LO */
uint8 max_recv_size[4]; /* HI-LO */
} *xdata= (struct XDATA*) responsedata;
break;
#else
case 0x65 :
XDPRINTF((2,0, "Packet Burst Connection Request not yet supportet"));
nw_debug=0;
completition = 0xfb; /* unknown request */
break;
int client_socket=GET_BE16(input->target_socket);
uint32 max_packet_size=min(sizeof(IPX_DATA),
GET_BE32(input->max_packet_size)-30);
U32_TO_BE32(max_packet_size + 30,
xdata->max_packet_size);
if (!burst_w)
burst_w=(BURST_W*)xcmalloc(sizeof(BURST_W));
xfree(burst_w->sendburst);
xfree(burst_w->send_buf);
xfree(burst_w->recv_buf);
burst_w->max_burst_data_size=
max_packet_size-sizeof(BURSTPACKET);
burst_w->sendburst=
(BURSTPACKET*)xcmalloc(max_packet_size);
burst_w->ud.udata.buf = (char*)(burst_w->sendburst);
burst_w->sendburst->type[0]=0x77;
burst_w->sendburst->type[1]=0x77;
burst_w->sendburst->streamtyp=2; /* BIG_SEND_BURST */
U32_TO_BE32(time(NULL), burst_w->sendburst->source_conn);
U16_TO_16(act_connection, burst_w->sendburst->source_conn);
/* we need to identify it */
memcpy(xdata->server_id,
burst_w->sendburst->source_conn, 4);
memcpy(burst_w->sendburst->dest_conn,
input->connid, 4);
burst_w->max_send_size=
min(max_burst_send_size,
GET_BE32(input->max_recv_size));
burst_w->send_buf=xcmalloc(burst_w->max_send_size);
burst_w->max_recv_size=
min(max_burst_recv_size,
GET_BE32(input->max_send_size));
burst_w->recv_buf=xcmalloc(burst_w->max_recv_size);
#if 0
U32_TO_BE32(0x1600, burst_w->sendburst->delaytime);
#endif
U32_TO_BE32(burst_w->max_recv_size, xdata->max_recv_size);
U32_TO_BE32(burst_w->max_send_size, xdata->max_send_size);
burst_w->ipx_pack_typ = PACKT_CORE;
burst_w->ud.opt.len = sizeof(uint8);
burst_w->ud.opt.maxlen = sizeof(uint8);
burst_w->ud.opt.buf = (char*)&(burst_w->ipx_pack_typ);
memcpy(&(burst_w->to_addr), &from_addr, sizeof(ipxAddr_t));
U16_TO_BE16(client_socket, burst_w->to_addr.sock);
burst_w->ud.addr.len = sizeof(ipxAddr_t);
burst_w->ud.addr.maxlen = sizeof(ipxAddr_t);
burst_w->ud.addr.buf = (char*)&(burst_w->to_addr);
data_len = sizeof(*xdata);
} else
#endif
{
XDPRINTF((2,0, "Packet Burst Connection Request not enabled"));
nw_debug=0;
completition = 0xfb; /* unknown request */
}
break;
case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */
XDPRINTF((2,0, "NDS Fragger Protokoll not supportet"));
@ -1485,7 +1608,7 @@ static int handle_ncp_serv(void)
(void) nw_init_connect();
last_sequence = -9999;
} else {
printf("WRONG TYPE 0x%x IN NWCONN\n", ncp_type);
XDPRINTF((1,0, "WRONG TYPE:0x%x", ncp_type));
completition = 0xfb;
}
@ -1602,10 +1725,17 @@ static void handle_after_bind()
case 0x14: /* Login Objekt, unencrypted passwords */
case 0x18: { /* crypt_keyed LOGIN */
int fnlen = (int) *(bindresponse + 3 * sizeof(int));
uint8 objname[48];
/* ncpserv have changed the structure */
set_guid(*((int*)bindresponse), *((int*)(bindresponse+sizeof(int))));
set_act_obj_id(*((uint32*)(bindresponse + 2 * sizeof(int))));
nw_setup_home_vol(fnlen, bindresponse + 3 * sizeof(int) +1);
if (ufunc==0x14) {
xstrmaxcpy(objname, requestdata+6, (int) *(requestdata+5));
} else if (ufunc==0x18){
xstrmaxcpy(objname, requestdata+14, (int) *(requestdata+13));
} else objname[0]='\0';
set_program_title(objname);
}
break;
@ -1623,7 +1753,9 @@ static void handle_after_bind()
uint8 dir_nam_len; /* len of dirname */
uint8 dir_name[1];
} *rinput = (struct RINPUT *) (bindresponse);
int result = nw_creat_queue(ncpresponse->connection,
int result = nw_creat_queue(
(int)ncpresponse->connection
| (((int)ncpresponse->high_connection) << 8),
input->queue_id,
input->queue_job,
rinput->dir_name,
@ -1666,7 +1798,124 @@ static void handle_after_bind()
ncp_response(ncprequest->sequence, ncprequest->task, completition, data_len);
}
extern int t_errno;
#if ENABLE_BURSTMODE
static int send_burst(int offset, int datasize, int flags)
{
BURSTPACKET *sb=burst_w->sendburst;
U32_TO_BE32(burst_w->packet_sequence++, sb->packet_sequence);
U32_TO_BE32(offset, sb->burstoffset);
U16_TO_BE16(datasize, sb->datasize);
U16_TO_BE16(0, sb->missing);
sb->flags = (uint8)flags;
memcpy(sb+1, burst_w->send_buf+offset, datasize);
burst_w->ud.udata.len =
burst_w->ud.udata.maxlen = datasize+sizeof(BURSTPACKET);
if (t_sndudata(FD_NCP_OUT, &(burst_w->ud)) < 0){
if (nw_debug) t_error("t_sndudata in NWCONN !OK");
return(-1);
}
return(0);
}
static void handle_burst_response(uint32 offset, int size)
{
BURSTPACKET *sb=burst_w->sendburst;
U16_TO_BE16(burst_w->burst_sequence, sb->burst_seq);
U16_TO_BE16(burst_w->burst_sequence+1, sb->ack_seq);
U32_TO_BE32(size, sb->burstsize);
while (size) {
int sendsize=min(size, burst_w->max_burst_data_size);
int flags=0;
size-=sendsize;
if (!size) flags|=0x10; /* EndOfBurst */
send_burst(offset, sendsize, flags);
#if 0
sleep_mu(1);
#endif
offset+=sendsize;
}
}
static void handle_burst(BURSTPACKET *bp, int len)
{
if (burst_w) {
uint32 burstoffset = GET_BE32(bp->burstoffset);
int burstsequence = GET_BE16(bp->burst_seq);
int datasize = GET_BE16(bp->datasize);
if (datasize && !(bp->flags & 0x80))
memcpy(burst_w->recv_buf+burstoffset, bp+1, datasize);
if (bp->flags & 0x10) { /* last packet, now action */
struct REQ {
uint8 function[4]; /* lo-hi 1=READ, 2=WRITE */
uint8 fhandle[4]; /* from open file */
uint8 reserved1[6]; /* all zero */
uint8 reserved2[2]; /* ??? c8,0 od. c9,f0 */
uint8 file_offset[4]; /* HI-LO */
uint8 file_size [4]; /* HI-LO */
uint8 data[2]; /* only Write */
} *req=(struct REQ*)(burst_w->recv_buf);
int function=GET_32(req->function);
if (function == 1 || function == 2) { /* Read or Write */
uint32 fhandle = GET_32(req->fhandle);
uint32 foffset = GET_BE32(req->file_offset);
uint32 fsize = GET_BE32(req->file_size);
if (function == 1) { /* Read Request */
struct XDATA {
uint8 resultcode[4]; /* lo-hi ,
* 0=noerror=OK,
* 1=init-err,
* 2=IO-err,
* 3=no data
*/
uint8 readbytes[4]; /* hi-lo */
} *xdata= (struct XDATA*)burst_w->send_buf;
int size = nw_read_file(fhandle,
burst_w->send_buf+sizeof(struct XDATA),
fsize, foffset);
if (size > -1) {
U32_TO_32(0, xdata->resultcode);
U32_TO_BE32(size, xdata->readbytes);
} else {
U32_TO_32(3, xdata->resultcode);
U32_TO_BE32(0, xdata->readbytes);
size=0;
}
burst_w->burst_sequence = burstsequence;
handle_burst_response(0, size+sizeof(struct XDATA));
} else { /* Write Request */
struct XDATA {
uint8 resultcode[4]; /* lo-hi ,
* 0=noerror=OK,
* 4=write error
*/
} *xdata= (struct XDATA*)burst_w->send_buf;
int size = nw_write_file(fhandle, req->data, fsize, foffset);
U32_TO_32(size==fsize ? 0 : 4, xdata->resultcode);
burst_w->burst_sequence = burstsequence;
handle_burst_response(0, sizeof(struct XDATA));
}
}
} else if (bp->flags & 0x80) {
int missing=GET_BE16(bp->missing);
uint8 *p=(uint8*)(bp+1);
burst_w->burst_sequence = burstsequence;
while (missing--){
int offs=GET_BE32(p);
int size=GET_BE16(p+4);
handle_burst_response(offs, size);
p+=6;
}
}
} else {
XDPRINTF((1, 0, "burst_w not allocated"));
}
}
#endif
static void close_all(void)
{
@ -1708,34 +1957,31 @@ static void set_sig(void)
signal(SIGINT, sig_quit);
signal(SIGPIPE, sig_pipe);
signal(SIGHUP, sig_hup);
#if USE_MMAP
signal(SIGBUS, sig_bus_mmap); /* in nwfile.c */
#endif
if (use_mmap)
signal(SIGBUS, sig_bus_mmap); /* in nwfile.c */
}
#include <sys/resource.h>
int main(int argc, char **argv)
{
if (argc != 6) {
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection nwbindsock echosock\n");
if (argc != 4 || 3!=sscanf(argv[3], "()INIT-:%x,%x,%x-",
&father_pid, &sock_nwbind, &sock_echo)) {
fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n");
exit(1);
} else father_pid = atoi(*(argv+1));
}
prog_title=argv[3];
setuid(0);
setgid(0);
init_tools(NWCONN, atoi(*(argv+3)));
act_connection = atoi(*(argv+1));
init_tools(NWCONN, act_connection);
memset(saved_readbuff, 0, sizeof(saved_readbuff));
XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s",
father_pid, *(argv+2), *(argv+3)));
XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%d",
father_pid, *(argv+2), act_connection));
adr_to_ipx_addr(&from_addr, *(argv+2));
act_connection = atoi(*(argv+3));
if (nw_init_connect()) exit(1);
act_pid = getpid();
sscanf(argv[4], "%x", &sock_nwbind);
sscanf(argv[5], "%x", &sock_echo);
#ifdef LINUX
set_emu_tli();
#endif
@ -1749,12 +1995,16 @@ int main(int argc, char **argv)
int conn = act_connection;
int result = ioctl(0, SIOCIPXNCPCONN, &conn);
XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result));
#if 0
if (result == 1) use_ipx_io++;
#endif
}
# endif
# endif
#endif
set_default_guid();
set_program_title(NULL);
ud.opt.len = sizeof(uint8);
ud.opt.maxlen = sizeof(uint8);
@ -1766,23 +2016,34 @@ int main(int argc, char **argv)
ud.udata.buf = (char*)&ipxdata;
U16_TO_BE16(0x3333, ncpresponse->type);
ncpresponse->task = (uint8) 1; /* allways 1 */
ncpresponse->reserved = (uint8) 0; /* allways 0 */
ncpresponse->connection = (uint8)act_connection;
ncpresponse->task = (uint8) 1; /* allways 1 */
ncpresponse->connection = (uint8)act_connection;
ncpresponse->high_connection = (uint8)(act_connection >> 8);
ipx_io.ubuf = readbuff;
ipx_io.size = sizeof(readbuff);
ipx_io.ncp_resp = (char*)&ipxdata;
ipx_io.resp_size= sizeof(ipxdata);
ipx_io.fh_r = 0;
ipx_io.fd_r = -1;
ipx_io.fh_w = 0;
ipx_io.fd_w = -1;
set_sig();
while (fl_get_int >= 0) {
int data_len ;
/* setpriority(PRIO_PROCESS, 0, 0); */
data_len = read(0, readbuff, sizeof(readbuff));
#ifdef SIOCIPXNCPCONN
if (use_ipx_io)
data_len = ioctl(0, SIOCIPXNCPCONN+1, &ipx_io);
else
#endif
data_len = read(0, readbuff, sizeof(readbuff));
/* this read is a pipe or a socket read,
* depending on CALL_NWCONN_OVER_SOCKET
*/
ncpresponse->connect_status = (uint8) 0;
/* new: 01-Nov-96 */
ncpresponse->task = ncprequest->task;
if (fl_get_int) {
if (fl_get_int == 1) get_new_debug();
@ -1791,6 +2052,9 @@ int main(int argc, char **argv)
if (data_len > 0) {
XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len));
ncpresponse->connect_status = (uint8) 0;
ncpresponse->task = ncprequest->task;
if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) {
/* this is a response packet */
data_len -= sizeof(NCPRESPONSE);
@ -1811,6 +2075,11 @@ int main(int argc, char **argv)
ncprequest->function, data_len);
}
saved_sequence = -1;
#if ENABLE_BURSTMODE
} else if (ncp_type == 0x7777) { /* BURST-MODE */
XDPRINTF((16, 0, "GOT BURSTPACKET"));
handle_burst((BURSTPACKET*)readbuff, data_len);
#endif
} else { /* this calls I must handle, it is a request */
int result;
requestlen = data_len - sizeof(NCPREQUEST);

View File

@ -1,5 +1,23 @@
#ifndef _NWCONN_H_
#define _NWCONN_H_
typedef struct {
int size; /* max. read size or write size */
char *ubuf; /* readbuf */
/* ------------------------------*/
char *ncp_resp; /* response packet */
int resp_size; /* max. size of response packet */
/* ------------------------------*/
int fh_r; /* NCP-Filehandle, read */
int fd_r; /* file-descriptor, read */
int fh_w; /* NCP-Filehandle, write */
int fd_w; /* file-descriptor, write */
} IPX_IO_RW;
extern IPX_IO_RW ipx_io;
extern int use_ipx_io;
extern int act_connection;
extern int act_pid;
#endif

12
nwdbm.c
View File

@ -1,4 +1,4 @@
/* nwdbm.c 17-Apr-97 data base for mars_nwe */
/* nwdbm.c 08-Jun-97 data base for mars_nwe */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -42,7 +42,9 @@
#define DBM_REMAINS_OPEN 1
int tells_server_version=1; /* default 1 since 12-Jan-97 */
int password_scheme=0; /* PW_SCHEME_CHANGE_PW; */
int password_scheme=0;
uint32 network_serial_nmbr=(uint32)NETWORK_SERIAL_NMBR;
uint16 network_appl_nmbr=(uint16)NETWORK_APPL_NMBR;
static int entry8_flags = 0;
@ -1790,6 +1792,10 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
if (auto_ins_user) auto_ins_user = atoi(buf);
} else if (16 == what) {
make_tests = atoi(buff);
} else if (70 == what) {
network_serial_nmbr=atou(buff);
} else if (71 == what) {
network_appl_nmbr=(uint16)atou(buff);
}
} /* while */
fclose(f);
@ -1930,7 +1936,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
int nw_init_dbm(char *servername, ipxAddr_t *adr)
/*
* routine inits bindery
* all dynamic objects and properties will be deletet.
* all dynamic objects and properties will be deleted.
* and the always needed properties will be created
* if not exist.
*/

View File

@ -70,6 +70,8 @@ typedef struct {
extern int tells_server_version;
extern int password_scheme;
extern uint32 network_serial_nmbr;
extern uint16 network_appl_nmbr;
#define PW_SCHEME_CHANGE_PW 1
#define PW_SCHEME_LOGIN 2

154
nwfile.c
View File

@ -1,4 +1,4 @@
/* nwfile.c 23-Apr-97 */
/* nwfile.c 02-Jun-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -27,8 +27,9 @@
#include "nwfile.h"
#include "connect.h"
#include "nwconn.h"
#if USE_MMAP
# include <sys/mman.h>
static got_sig_bus=0;
void sig_bus_mmap(int rsig)
{
@ -36,7 +37,6 @@ void sig_bus_mmap(int rsig)
XDPRINTF((2,0, "Got sig_bus"));
signal(SIGBUS, sig_bus_mmap);
}
#endif
static FILE_HANDLE file_handles[MAX_FILE_HANDLES_CONN];
#define HOFFS 0
@ -44,19 +44,19 @@ static int anz_fhandles=0;
static int new_file_handle(uint8 *unixname, int task)
{
int rethandle = HOFFS -1;
int fhandle = HOFFS -1;
FILE_HANDLE *fh=NULL;
while (++rethandle < anz_fhandles) {
fh=&(file_handles[rethandle]);
while (++fhandle < anz_fhandles) {
fh=&(file_handles[fhandle]);
if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */
rethandle++;
fhandle++;
break;
} else fh=NULL;
}
if (fh == NULL) {
if (anz_fhandles < MAX_FILE_HANDLES_CONN) {
fh=&(file_handles[anz_fhandles]);
rethandle = ++anz_fhandles;
fhandle = ++anz_fhandles;
} else {
XDPRINTF((1, 0, "No more free file handles"));
return(0); /* no free handle anymore */
@ -71,13 +71,32 @@ static int new_file_handle(uint8 *unixname, int task)
fh->fh_flags = 0;
fh->f = NULL;
XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s",
rethandle, anz_fhandles, unixname));
return(rethandle);
fhandle, anz_fhandles, unixname));
if (fhandle == ipx_io.fh_r){
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
}
if (fhandle == ipx_io.fh_w){
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
}
return(fhandle);
}
static int free_file_handle(int fhandle)
{
int result=-0x88;
if (fhandle == ipx_io.fh_r){
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
}
if (fhandle == ipx_io.fh_w){
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
}
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) {
@ -85,13 +104,11 @@ static int free_file_handle(int fhandle)
if (fh->f) ext_pclose(fh->f);
fh->f = NULL;
} else {
#if USE_MMAP
if (fh->p_mmap) {
if (use_mmap && fh->p_mmap) {
munmap(fh->p_mmap, fh->size_mmap);
fh->p_mmap = NULL;
fh->size_mmap = 0;
}
#endif
close(fh->fd);
}
if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags)
@ -138,6 +155,10 @@ void init_file_module(int task)
}
}
}
ipx_io.fh_r= 0;
ipx_io.fd_r=-1;
ipx_io.fh_w= 0;
ipx_io.fd_w=-1;
}
static int xsetegid(gid_t gid)
@ -378,8 +399,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
completition=-0xfe;
}
}
#if USE_MMAP
if (fh->fd > -1 && !dowrite) {
if (use_mmap && fh->fd > -1 && !dowrite) {
fh->size_mmap = fh->offd=lseek(fh->fd, 0L, SEEK_END);
if (fh->size_mmap > 0) {
fh->p_mmap = mmap(NULL,
@ -393,7 +413,6 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
}
}
}
#endif
}
}
if (fh->fd > -1) {
@ -422,7 +441,7 @@ file_creat_open_ret:
char fname[200];
if (!fd_2_fname(fhandle, fname, sizeof(fname))){
FILE_HANDLE *fh=fd_2_fh(fhandle);
dprintf("Open/creat fd=%d, fn=`%s`, openmode=%s",
xdprintf(1,0,"Open/creat fd=%d, fn=`%s`, openmode=%s",
fhandle, fname, (fh && (fh->fh_flags &FH_OPENED_RO)) ? "RO" : "RW" );
}
})
@ -451,7 +470,7 @@ int nw_close_file(int fhandle, int reset_reuse)
MDEBUG(D_FH_OPEN, {
char fname[200];
int r=fd_2_fname(fhandle, fname, sizeof(fname));
dprintf("nw_close_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
xdprintf(1,0,"nw_close_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
})
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
@ -467,13 +486,11 @@ int nw_close_file(int fhandle, int reset_reuse)
}
fh->f = NULL;
} else {
#if USE_MMAP
if (fh->p_mmap) {
if (use_mmap && fh->p_mmap) {
munmap(fh->p_mmap, fh->size_mmap);
fh->p_mmap = NULL;
fh->size_mmap = 0;
}
#endif
result=close(fh->fd);
}
fh->fd = -1;
@ -503,7 +520,7 @@ int nw_commit_file(int fhandle)
MDEBUG(D_FH_FLUSH, {
char fname[200];
int r=fd_2_fname(fhandle, fname, sizeof(fname));
dprintf("nw_commit_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
xdprintf(1,0,"nw_commit_file: fd=%d, fn=`%s`,r=%d", fhandle, fname, r);
})
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]);
@ -556,7 +573,7 @@ static void open_pipe_command(FILE_HANDLE *fh, int dowrite)
fh->fd = (fh->f) ? fileno(fh->f->fildes[dowrite ? 0 : 1]) : -3;
}
int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset)
{
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
@ -576,42 +593,40 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->f->flags & 1) return(-0x57);
fh->f->flags |= 1;
}
} else {
#if USE_MMAP
if (fh->p_mmap) {
while (1) {
if (offset < fh->size_mmap) {
if (size + offset > fh->size_mmap)
size = fh->size_mmap - offset;
memcpy(data, fh->p_mmap+offset, size);
if (got_sig_bus) {
fh->size_mmap = lseek(fh->fd, 0L, SEEK_END);
got_sig_bus = 0;
} else
break;
} else {
size=-1;
} else if (use_mmap && fh->p_mmap) {
while (1) {
if (offset < fh->size_mmap) {
if (size + offset > fh->size_mmap)
size = fh->size_mmap - offset;
memcpy(data, fh->p_mmap+offset, size);
if (got_sig_bus) {
fh->size_mmap = lseek(fh->fd, 0L, SEEK_END);
got_sig_bus = 0;
} else
break;
}
} /* while */
} else {
#endif
if (fh->offd != (long)offset) {
fh->offd=lseek(fh->fd, offset, SEEK_SET);
if (fh->offd < 0) {
XDPRINTF((5,0,"read-file failed in lseek"));
}
} else {
size=-1;
break;
}
} /* while */
} else {
if (use_ipx_io || fh->offd != (long)offset) {
fh->offd=lseek(fh->fd, offset, SEEK_SET);
if (fh->offd < 0) {
XDPRINTF((5,0,"read-file failed in lseek"));
}
if (fh->offd > -1L) {
if ((size = read(fh->fd, data, size)) > -1)
fh->offd+=(long)size;
else {
XDPRINTF((5,0,"read-file failed in read"));
}
} else size = -1;
#if USE_MMAP
}
#endif
if (fh->offd > -1L) {
if ((size = read(fh->fd, data, size)) > -1) {
fh->offd+=(long)size;
if (use_ipx_io) {
ipx_io.fh_r=fhandle+1;
ipx_io.fd_r=fh->fd;
}
} else {
XDPRINTF((5,0,"read-file failed in read"));
}
} else size = -1;
}
if (size == -1) size=0;
return(size);
@ -620,7 +635,7 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
return(-0x88); /* wrong filehandle */
}
int nw_seek_datei(int fhandle, int modus)
int nw_seek_file(int fhandle, int modus)
{
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
@ -642,7 +657,7 @@ int nw_seek_datei(int fhandle, int modus)
}
int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset)
{
if (fhandle > HOFFS && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]);
@ -653,12 +668,16 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
return(size ? write(fh->fd, data, size) : 0);
} else {
if (fh->offd != (long)offset)
if (use_ipx_io || fh->offd != (long)offset)
fh->offd = lseek(fh->fd, offset, SEEK_SET);
if (size) {
if (fh->offd > -1L) {
size = write(fh->fd, data, size);
fh->offd+=(long)size;
if (use_ipx_io&&size>0) {
ipx_io.fh_w=fhandle+1;
ipx_io.fd_w=fh->fd;
}
} else size = -1;
return(size);
} else { /* truncate FILE */
@ -723,7 +742,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset,
return(-0x88); /* wrong filehandle */
}
int nw_lock_file(int fhandle, int offset, int size, int do_lock)
int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock)
{
int result=-0x88; /* wrong filehandle */
if (fhandle > HOFFS && (fhandle <= anz_fhandles)) {
@ -748,7 +767,18 @@ int nw_lock_file(int fhandle, int offset, int size, int do_lock)
*/
flockd.l_start = (offset & 0x7fffffff);
#endif
flockd.l_len = size;
if (size == MAX_U32) {
/* This is only a guess, but a size of 0xffffffff means to lock
* the rest of the file, starting from the offset, to do this with
* linux, a size of 0 has to be passed to the fcntl function.
* ( Peter Gerhard )
*
*/
flockd.l_len = 0;
} else
flockd.l_len = (size & 0x7fffffff);
result = fcntl(fh->fd, F_SETLK, &flockd);
XDPRINTF((2, 0, "nw_%s_datei result=%d, fh=%d, offset=%d, size=%d",
(do_lock) ? "lock" : "unlock", result, fhandle, offset, size));
@ -760,7 +790,7 @@ leave:
MDEBUG(D_FH_LOCK, {
char fname[200];
(void)fd_2_fname(fhandle, fname, sizeof(fname));
dprintf("nw_%s_datei: fd=%d, fn=`%s`,r=0x%x, offs=%d, len=%d",
xdprintf(1,0,"nw_%s_datei: fd=%d, fn=`%s`,r=0x%x, offs=%d, len=%d",
(do_lock) ? "lock" : "unlock",
fhandle, fname, -result, offset, size);
})

View File

@ -1,4 +1,4 @@
/* nwfile.h 23-Apr-97 */
/* nwfile.h 02-Jun-97 */
#ifndef _NWFILE_H_
#define _NWFILE_H_
#include "nwqueue.h"
@ -7,10 +7,8 @@ typedef struct {
int task; /* for which task */
int fd; /* filehandle from system open/creat */
long offd; /* actual file offset */
#if USE_MMAP
uint8 *p_mmap; /* for use with mmap */
int size_mmap;
#endif
time_t tmodi; /* modification TIME */
FILE_PIPE *f; /* for PIPE */
int fh_flags; /* 2 = PIPE */
@ -42,14 +40,14 @@ extern int nw_commit_file(int fhandle);
extern uint8 *file_get_unix_name(int fhandle);
extern int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset);
extern int nw_seek_datei(int fhandle, int modus);
extern int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset);
extern int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset);
extern int nw_seek_file(int fhandle, int modus);
extern int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset);
extern int nw_server_copy(int qfhandle, uint32 qoffset,
int zfhandle, uint32 zoffset,
uint32 size);
extern int nw_lock_file(int fhandle, int offset, int size, int do_lock);
extern int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock);
extern int fd_2_fname(int fhandle, char *buf, int bufsize);
extern FILE_HANDLE *fd_2_fh(int fhandle);

336
nwfname.c Normal file
View File

@ -0,0 +1,336 @@
/* nwfname.c 17-Jun-97 */
/* (C)opyright (C) 1997 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* some code and ideas from Victor Khimenko <khim@mccme.ru>
*/
#include "net.h"
#include "unxfile.h"
#include "nwvolume.h"
#include <utime.h>
#include "nwfname.h"
#include <limits.h>
typedef uint8 CHARTABLE[256];
static uint8 *last_filename=NULL;
static ino_t last_st_ino=0;
static CHARTABLE *conversiontable=NULL;
/* there exists 5 tables
* 0 = dos2unix
* 1 = unix2dos
* 2 = down2up 'dosname'
* 3 = up2down 'dosname'
* 4 = up2down 'unixname'
*/
void init_nwfname(char *convfile)
{
FILE *f;
new_str(last_filename, NULL);
last_st_ino=0;
if (conversiontable) return;
if (NULL != (f=fopen(convfile, "rb")))
conversiontable=(CHARTABLE*)xcmalloc(sizeof(CHARTABLE)*5);
if (conversiontable) {
int i=fread(conversiontable, sizeof(CHARTABLE), 5, f);
if (i < 4)
xfree(conversiontable);
else if (i==4) {
/* now we get the last table from the other */
int i=0;
while(i++ < 255) {
uint8 dc=conversiontable[1][i];
uint8 lo=conversiontable[3][dc];
conversiontable[4][i]=
conversiontable[0][lo];
}
}
}
XDPRINTF((2,0, "conversiontable: `%s` %s loaded",
convfile, (conversiontable==NULL) ? "not" : ""));
if (f) fclose(f);
}
uint8 *up_fn(uint8 *ss)
{
uint8 *s=ss;
if (!s) return((uint8*)NULL);
if (conversiontable)
for (;*s;s++) *s=conversiontable[2][*s];
else
for (;*s;s++) *s=up_char(*s);
return(ss);
}
uint8 *down_fn(uint8 *ss)
{
uint8 *s=ss;
if (!s) return((uint8*)NULL);
if (conversiontable)
for (;*s;s++) *s=conversiontable[3][*s];
else
for (;*s;s++) *s=down_char(*s);
return(ss);
}
uint8 *dos2unixcharset(uint8 *ss)
{
uint8 *s=ss;
if (!conversiontable) return ss;
if (!s) return((uint8*)NULL);
for (;*s;s++) *s=conversiontable[0][*s];
return(ss);
}
uint8 *unix2doscharset(uint8 *ss)
{
uint8 *s=ss;
if (!conversiontable) return ss;
if (!s) return((uint8*)NULL);
for (;*s;s++) *s=conversiontable[1][*s];
return(ss);
}
int dfn_imatch(uint8 a, uint8 b)
/* returns 1 if a matched b ignoring case for 'dos/os2' filename chars */
{
if (a==b) return(1);
if (!conversiontable)
return(down_char(a) == down_char(b));
return(conversiontable[3][a] == conversiontable[3][b]);
}
int ufn_imatch(uint8 a, uint8 b)
/* returns 1 if a matched b ignoring case for unix filename chars */
{
if (a==b) return(1);
if (!conversiontable)
return(down_char(a) == down_char(b));
return(conversiontable[4][a] == conversiontable[4][b]);
}
#if PERSISTENT_SYMLINKS
static dev_t last_st_dev=0;
static int last_islink=0;
typedef struct {
dev_t st_dev;
ino_t st_ino;
char *filename;
} S_PATH_INODE;
static int get_full_path(char *path)
/* sets last_filename */
{
char newpath[PATH_MAX];
char *npath=newpath;
char *maxpath=newpath+PATH_MAX-1;
char aktpath[PATH_MAX];
char *pp=path;
struct stat statb_buf;
struct stat *statbuf=&statb_buf;
int countlinks = 10; /* max. 10 links */
*npath++='/'; /* we begin at '/' */
last_islink = 0;
last_st_ino = 0;
while (*pp) {
char *save_npath;
if (pp[0] == '.'){
if (pp[1] == '.' && (pp[2] == '/' || pp[2] == '\0') ) {
pp+=2;
while(npath > newpath && *(npath-1) != '/')
--npath;
continue;
} else if (pp[1] == '/') {
pp++;
continue;
}
} else if (pp[0] == '/') {
pp++;
continue;
}
save_npath=npath;
while (*pp && *pp != '/') {
if (npath == maxpath) { /* path too long */
last_st_ino = 0;
return(-99);
}
*npath++ = *pp++;
}
*npath='\0';
if (lstat(newpath, statbuf)){
*save_npath='\0';
new_str(last_filename, newpath);
return(-1);
}
if (S_ISLNK(statbuf->st_mode)) {
int len=readlink(newpath, aktpath, PATH_MAX-1);
if (len < 0 || !countlinks-- ) { /* new links */
last_st_ino = 0;
return(-98);
}
aktpath[len]='\0';
pp=aktpath;
if (aktpath[0] == '/') {
npath=newpath+1;
++pp;
} else {
npath=save_npath;
}
last_islink++;
} else {
last_st_dev = statbuf->st_dev;
last_st_ino = statbuf->st_ino;
last_islink = 0;
}
}
new_str(last_filename, newpath);
return(0);
}
int s_stat(char *path, struct stat *statbuf, S_STATB *stb)
{
int result=0;
if (lstat(path, statbuf)) {
if (get_full_path(path) || lstat(last_filename, statbuf)) {
result=-1;
} else if (stb) {
stb->st_dev=last_st_dev;
stb->st_ino=last_st_ino;
stb->islink=last_islink;
}
} else {
if (stb) {
stb->st_dev=statbuf->st_dev;
stb->st_ino=statbuf->st_ino;
stb->islink=S_ISLNK(statbuf->st_mode);
}
if (S_ISLNK(statbuf->st_mode)) {
if (statbuf->st_ino == last_st_ino && statbuf->st_dev == last_st_dev) {
if (lstat(last_filename, statbuf)) {
last_st_ino=0;
result=-1;
goto s_stat_ret;
}
if (!S_ISLNK(statbuf->st_mode))
goto s_stat_ret;
}
if (get_full_path(path) || lstat(last_filename, statbuf)) {
last_st_ino=0;
result=-1;
}
}
}
s_stat_ret:
MDEBUG(D_FN_NAMES, {
xdprintf(1,0,"s_stat_ret: result=%d, path=`%s`, last_fname=`%s`",
result, path, last_filename);
})
return(result);
}
static int get_linked_name(char *path, S_STATB *stb,
char **fname, int mode)
{
S_STATB stbbuf;
struct stat statbuf_buf;
struct stat *statbuf=&statbuf_buf;
int result=0;
if (!stb) {
stb=&stbbuf;
stb->st_ino=0;
}
if (!stb->st_ino || (stb->islink
&& (stb->st_ino != last_st_ino
|| stb->st_dev != last_st_dev))) {
if (lstat(path, statbuf)) {
if (get_full_path(path) || lstat(last_filename, statbuf)) {
result=-1;
goto get_linked_name_ret;
} else if (stb) {
stb->st_dev=last_st_dev;
stb->st_ino=last_st_ino;
stb->islink=last_islink;
}
*fname = last_filename;
goto get_linked_name_ret;
}
stb->st_dev=statbuf->st_dev;
stb->st_ino=statbuf->st_ino;
stb->islink=S_ISLNK(statbuf->st_mode);
}
if (stb->islink) {
if (stb->st_ino == last_st_ino && stb->st_dev == last_st_dev) {
if (lstat((char *)last_filename, statbuf)) {
last_st_ino=0;
result=-1;
goto get_linked_name_ret;
}
if (!S_ISLNK(statbuf->st_mode)) {
*fname = last_filename;
goto get_linked_name_ret;
}
}
if (get_full_path(path) || lstat(last_filename, statbuf)) {
last_st_ino=0;
result=-1;
goto get_linked_name_ret;
}
*fname=last_filename;
} else
*fname=path;
get_linked_name_ret:
MDEBUG(D_FN_NAMES, {
xdprintf(1,0,"get_l_name: result=%d, path=`%s`, fname=`%s`",
result, path, *fname);
})
return(result);
}
int s_utime(char *fn, struct utimbuf *ut, S_STATB *stb)
{
char *fnbuf=fn;
int result=get_linked_name(fn, stb, &fnbuf, 0);
if (!result) {
result=utime(fnbuf, ut);
}
return(result);
}
int s_chmod(char *fn, umode_t mode, S_STATB *stb)
{
char *fnbuf=fn;
int result=get_linked_name(fn, stb, &fnbuf, 0);
if (!result) {
result=chmod(fnbuf, mode);
}
return(result);
}
#endif

35
nwfname.h Normal file
View File

@ -0,0 +1,35 @@
/* nwfname.h 17-Jun-97 */
#ifndef _NWFNAME_H_
#define _NWFNAME_H_ 1
extern void init_nwfname(char *convfile);
extern uint8 *up_fn(uint8 *ss);
extern uint8 *down_fn(uint8 *ss);
extern uint8 *dos2unixcharset(uint8 *ss);
extern uint8 *unix2doscharset(uint8 *ss);
extern int dfn_imatch(uint8 a, uint8 b);
extern int ufn_imatch(uint8 a, uint8 b);
#if PERSISTENT_SYMLINKS
typedef struct {
dev_t st_dev;
ino_t st_ino;
int islink; /* if symblic link */
} S_STATB;
extern int s_stat(char *path, struct stat *statbuf, S_STATB *stb);
extern int s_utime(char *fn, struct utimbuf *ut, S_STATB *stb);
extern int s_chmod(char *fn, umode_t mode, S_STATB *stb);
#else
# define s_stat(path, statbuf, stb) \
stat((path), (statbuf))
# define s_utime(fn, ut, stb) \
utime((fn), (ut))
# define s_chmod(fn, mode, stb) \
chmod((fn), (mode))
#endif
#endif

View File

@ -307,6 +307,7 @@ int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
memcpy(&(jo->q.o), queue_job, sizeof(QUEUE_JOB_OLD));
jo->q.o.job_id[0] = (uint8) jo_id;
jo->q.o.client_connection = (uint8)connection;
jo->q.o.client_task = (uint8)0xfe; /* ?? */
U32_TO_BE32(1, jo->q.o.client_id); /* SU */
set_entry_time(jo->q.o.job_entry_time);
@ -338,8 +339,10 @@ int nw_creat_queue(int connection, uint8 *queue_id, uint8 *queue_job,
U16_TO_BE16(0xffff, jo->q.n.record_in_use);
U32_TO_BE32(0x0, jo->q.n.record_previous);
U32_TO_BE32(0x0, jo->q.n.record_next);
memset(jo->q.n.client_connection, 0, 4);
jo->q.n.client_connection[0] = (uint8)connection;
jo->q.n.client_connection[2] = 0;
jo->q.n.client_connection[3] = 0;
U16_TO_16(connection, jo->q.n.client_connection);
memset(jo->q.n.client_task, 0, 4);
jo->q.n.client_task[0] = (uint8)0xfe; /* ?? */
U32_TO_BE32(1, jo->q.n.client_id); /* SU */

156
nwroute.c
View File

@ -1,4 +1,4 @@
/* nwroute.c 15-Apr-97 */
/* nwroute.c 02-Jun-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -28,7 +28,8 @@ typedef struct {
} NW_ROUTES;
static int anz_routes=0;
static NW_ROUTES *nw_routes[MAX_NW_ROUTES];
static int max_nw_routes=0;
static NW_ROUTES **nw_routes=NULL;
typedef struct {
uint8 *name; /* Server Name */
@ -40,7 +41,8 @@ typedef struct {
} NW_SERVERS;
static int anz_servers=0;
static NW_SERVERS *nw_servers[MAX_NW_SERVERS];
static int max_nw_servers=0;
static NW_SERVERS **nw_servers=NULL;
static void insert_delete_net(uint32 destnet,
uint32 rnet, /* routernet */
@ -62,7 +64,7 @@ static void insert_delete_net(uint32 destnet,
if (!destnet || destnet == internal_net) return;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up) {
if (nd->net == destnet) {
@ -82,9 +84,15 @@ static void insert_delete_net(uint32 destnet,
if (k == anz_routes) { /* no route slot found */
if (do_delete) return; /* nothing to delete */
if (freeslot < 0) {
if (anz_routes == MAX_NW_ROUTES) {
XDPRINTF((1, 0, "too many routes > %d, increase MAX_NW_ROUTES in config.h", anz_routes));
return;
if (anz_routes == max_nw_routes) {
int new_max_nw = max_nw_routes+5;
NW_ROUTES **new_nwr
=(NW_ROUTES**)xcmalloc(new_max_nw*sizeof(NW_ROUTES*));
if (max_nw_servers)
memcpy(new_nwr, nw_routes, max_nw_routes*sizeof(NW_ROUTES*));
xfree(nw_routes);
nw_routes=new_nwr;
max_nw_routes=new_max_nw;
}
nw_routes[k] = (NW_ROUTES*)xmalloc(sizeof(NW_ROUTES));
anz_routes++;
@ -142,7 +150,7 @@ NW_NET_DEVICE *find_netdevice(uint32 network)
int l=2;
while (l--) {
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && nd->net == net) {
XDPRINTF((3, 0, "found netdevive %s, frame=%d, ticks=%d",
@ -163,7 +171,7 @@ static NW_NET_DEVICE *find_device_by_net(uint32 net)
/* return the device of this net I hope */
{
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && nd->net == net) return(nd);
}
@ -205,9 +213,15 @@ void insert_delete_server(uint8 *name, /* Server Name */
if (do_delete) return; /* nothing to delete */
if (freeslot < 0) {
if (anz_servers == MAX_NW_SERVERS) {
XDPRINTF((1, 0, "too many servers > %d, increase MAX_NW_SERVERS in config.h", anz_servers));
return;
if (anz_servers == max_nw_servers) {
int new_max_nw = max_nw_servers+5;
NW_SERVERS **new_nws
=(NW_SERVERS**)xcmalloc(new_max_nw*sizeof(NW_SERVERS*));
if (max_nw_servers)
memcpy(new_nws, nw_servers, max_nw_servers*sizeof(NW_SERVERS*));
xfree(nw_servers);
nw_servers=new_nws;
max_nw_servers=new_max_nw;
}
nw_servers[k] = (NW_SERVERS*)xcmalloc(sizeof(NW_SERVERS));
anz_servers++;
@ -262,14 +276,18 @@ static int rmode; /* 0=normal, 1=shutdown response */
/* 10=request */
static int rentries=0;
static uint8 rip_buff[2 + MAX_RIP_ENTRIES * 8];
/* operation + max. 50 RIPS */
static int max_rip_entries=0;
static uint8 *rip_buff=NULL;
static void init_rip_buff(uint32 net, int mode)
{
rnet = net;
rentries = 0;
rmode = mode;
if (!rip_buff) {
max_rip_entries=10;
rip_buff=xcmalloc(2+max_rip_entries*8);
}
U16_TO_BE16((mode > 9) ? 1 : 2, rip_buff); /* rip request or response */
}
@ -277,15 +295,21 @@ static void ins_rip_buff(uint32 net, uint16 hops, uint16 ticks)
{
if (!net) return;
if (net != rnet || (!rentries && net == internal_net)) {
if (rentries < MAX_RIP_ENTRIES) {
uint8 *p=rip_buff+2+(rentries*8);
U32_TO_BE32(net, p);
U16_TO_BE16(hops, p+4);
U16_TO_BE16(ticks, p+6);
rentries++;
} else {
XDPRINTF((1, 0, "too many rips > %d, increase MAX_RIP_ENTRIES in config.h", MAX_RIP_ENTRIES));
uint8 *p;
if (rentries >= max_rip_entries) {
int new_rip_entries=max_rip_entries+5;
uint8 *new_ripbuf=xcmalloc(2 + new_rip_entries*8);
if (max_rip_entries)
memcpy(new_ripbuf, rip_buff, 2 + max_rip_entries*8);
xfree(rip_buff);
rip_buff=new_ripbuf;
max_rip_entries=new_rip_entries;
}
p=rip_buff+2+(rentries*8);
U32_TO_BE32(net, p);
U16_TO_BE16(hops, p+4);
U16_TO_BE16(ticks, p+6);
rentries++;
}
}
@ -303,7 +327,7 @@ static void build_rip_buff(uint32 destnet)
}
k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && (is_wild || nd->net == destnet))
ins_rip_buff(nd->net, (rmode==1) ? 16 : 1, nd->ticks+1);
@ -368,9 +392,10 @@ static void send_rip_broadcast(int mode)
/* mode=2, shutdown */
{
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */
if (nd->is_up && (nd->ticks < 7 || mode)) {
/* isdn devices should not get RIP broadcasts everytime */
init_rip_buff(nd->net, (mode == 2) ? 1 : 0);
build_rip_buff(MAX_U32);
send_rip_buff(NULL);
@ -381,7 +406,7 @@ static void send_rip_broadcast(int mode)
void rip_for_net(uint32 net)
{
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && nd->ticks < 7) { /* isdn devices should not get RIP broadcasts everytime */
init_rip_buff(nd->net, 10);
@ -527,7 +552,7 @@ static void send_sap_broadcast(int mode)
/* mode=2, shutdown */
{
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && (nd->ticks < 7 || mode)) {
/* isdn devices should not get SAP broadcasts everytime */
@ -578,9 +603,9 @@ void print_routing_info(int force)
time_t xtime;
time(&xtime);
fprintf(f, "%s", ctime(&xtime) );
fprintf(f, "<--------- %d Devices ---------------->\n", anz_net_devices);
fprintf(f, "<--------- %d Devices ---------------->\n", count_net_devices);
fprintf(f, "%-15s %-15s %5s Network Status\n", "DevName", "Frame", "Ticks");
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
uint8 frname[30];
NW_NET_DEVICE *nd=net_devices[k];
(void) get_frame_name(frname, nd->frame);
@ -648,7 +673,7 @@ void send_sap_rip_broadcast(int mode)
/* mode=3, update routes */
{
static int flipflop=1;
int force_print_routes=(mode == 1);
int force_print_routes=(mode == 1) ? 1 : 0;
if (auto_detect_interfaces)
force_print_routes += look_for_interfaces();
if (mode) {
@ -692,12 +717,12 @@ static void query_sap_on_net(uint32 net)
void get_servers(void)
{
int k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
NW_NET_DEVICE *nd=net_devices[k];
if (nd->is_up && nd->ticks < 7)
query_sap_on_net(nd->net); /* only fast routes */
}
if (!anz_net_devices) query_sap_on_net(internal_net);
if (!count_net_devices) query_sap_on_net(internal_net);
}
@ -712,6 +737,18 @@ int dont_send_wdog(ipxAddr_t *addr)
return(0);
}
void realloc_net_devices(void)
{
int new_max_netd=max_net_devices+2;
NW_NET_DEVICE **new_nd=(NW_NET_DEVICE**)
xcmalloc(new_max_netd*sizeof(NW_NET_DEVICE*));
if (max_net_devices)
memcpy(new_nd, net_devices, max_net_devices*sizeof(NW_NET_DEVICE*));
xfree(net_devices);
net_devices=new_nd;
max_net_devices=new_max_netd;
}
/* ---------------------------------------------------- */
int test_ins_device_net(uint32 rnet)
{
@ -721,7 +758,7 @@ int test_ins_device_net(uint32 rnet)
int foundfree=-1; /* first matching/free entry */
NW_NET_DEVICE *nd;
if (!rnet || rnet == internal_net) return(0);
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
nd=net_devices[k];
if (!nd->is_up) {
if (nd->net == rnet) {
@ -740,7 +777,7 @@ int test_ins_device_net(uint32 rnet)
int framefound = -1;
k = foundfree - 1;
foundfree = -1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
nd = net_devices[k];
if (!nd->is_up && !nd->net) {
int dfound = !strcmp(nd->devname, rnetdevname);
@ -768,32 +805,31 @@ int test_ins_device_net(uint32 rnet)
}
if ( foundfree < 0 ) {
if (anz_net_devices < MAX_NET_DEVICES) {
NW_NET_DEVICE **pnd;
int matched=0;
k=-1;
while (++k < anz_net_devices) {
nd = net_devices[k];
if (nd->wildmask&3) {
int dfound = !strcmp(nd->devname, rnetdevname);
int ffound = nd->frame == rnetframe;
if ( (dfound && ffound) || (dfound && (nd->wildmask&2) )
|| (ffound && (nd->wildmask&1))) {
pnd=&(net_devices[anz_net_devices++]);
*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE));
(*pnd)->wildmask = nd->wildmask;
(*pnd)->ticks = nd->ticks;
matched++;
nd=*pnd;
break;
}
NW_NET_DEVICE **pnd;
int matched=0;
k=-1;
if (count_net_devices >= max_net_devices)
realloc_net_devices();
while (++k < count_net_devices) {
nd = net_devices[k];
if (nd->wildmask&3) {
int dfound = !strcmp(nd->devname, rnetdevname);
int ffound = nd->frame == rnetframe;
if ( (dfound && ffound) || (dfound && (nd->wildmask&2) )
|| (ffound && (nd->wildmask&1))) {
pnd=&(net_devices[count_net_devices++]);
*pnd= (NW_NET_DEVICE*)xcmalloc(sizeof(NW_NET_DEVICE));
(*pnd)->wildmask = nd->wildmask;
(*pnd)->ticks = nd->ticks;
matched++;
nd=*pnd;
break;
}
}
if (!matched) return(0);
} else {
XDPRINTF((1, 0, "too many devices > %d, increase MAX_NET_DEVICES in config.h", anz_net_devices));
return(0);
}
if (!matched) return(0);
} else {
nd = net_devices[foundfree];
}
@ -830,7 +866,7 @@ static int look_for_interfaces(void)
NW_NET_DEVICE *nd;
int k = -1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
nd=net_devices[k];
if (nd->is_up == 2) nd->is_up = -2; /* this will be put DOWN */
}
@ -844,7 +880,7 @@ static int look_for_interfaces(void)
if (rnet > 0L && !(flags & 2)) { /* not internal */
int found=0;
k=-1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
nd=net_devices[k];
if (nd->net == rnet) {
found++;
@ -859,7 +895,7 @@ static int look_for_interfaces(void)
fclose(f);
k = -1;
while (++k < anz_net_devices) {
while (++k < count_net_devices) {
nd=net_devices[k];
if (nd->is_up < 0) {
int j;

View File

@ -1,4 +1,4 @@
/* nwroute1.c 08-Feb-96 */
/* nwroute1.c 02-Jun-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -28,7 +28,8 @@ typedef struct {
} NW_SERVERS;
static int anz_servers=0;
static NW_SERVERS *nw_servers[MAX_NW_SERVERS];
static int max_nw_servers=0;
static NW_SERVERS **nw_servers=NULL;
void insert_delete_server(uint8 *name, /* Server Name */
int styp, /* Server Typ */
@ -58,9 +59,15 @@ void insert_delete_server(uint8 *name, /* Server Name */
if (k == anz_servers) { /* server not found */
if (do_delete) return; /* nothing to delete */
if (freeslot < 0) {
if (anz_servers == MAX_NW_SERVERS) {
XDPRINTF((1, 0, "too many servers=%d, increase MAX_NW_SERVERS in config.h", anz_servers));
return;
if (anz_servers == max_nw_servers) {
int new_max_nw = max_nw_servers+5;
NW_SERVERS **new_nws
=(NW_SERVERS**)xcmalloc(new_max_nw*sizeof(NW_SERVERS*));
if (max_nw_servers)
memcpy(new_nws, nw_servers, max_nw_servers*sizeof(NW_SERVERS*));
xfree(nw_servers);
nw_servers=new_nws;
max_nw_servers=new_max_nw;
}
nw_servers[k] = (NW_SERVERS*)xcmalloc(sizeof(NW_SERVERS));
anz_servers++;
@ -170,6 +177,11 @@ void send_sap_rip_broadcast(int mode)
}
}
void realloc_net_devices(void)
{
/* dummy */
}
int dont_send_wdog(ipxAddr_t *addr)
/* returns != 0 if tics are to high for wdogs */
{

176
nwserv.c
View File

@ -1,4 +1,4 @@
/* nwserv.c 12-Apr-97 */
/* nwserv.c 02-Jun-97 */
/* MAIN Prog for NWSERV + NWROUTED */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
@ -36,8 +36,9 @@ int print_route_mode = 0; /* append */
char *pr_route_info_fn = NULL; /* filename */
int wdogs_till_tics = 0; /* send wdogs to all */
/* <========== DEVICES ==========> */
int anz_net_devices=0;
NW_NET_DEVICE *net_devices[MAX_NET_DEVICES];
int count_net_devices=0;
int max_net_devices=0;
NW_NET_DEVICE **net_devices=NULL;
#if !IN_NWROUTED
uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */
@ -102,7 +103,11 @@ static int pid_ncpserv = -1;
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
static int pid_nwbind = -1;
#if !IN_NWROUTED
static int sock_nwbind = -1;
#endif
static int fd_nwbind_in = -1; /* ctrl-pipe in from nnwbind */
static time_t akttime_stamp = 0;
@ -111,7 +116,7 @@ static time_t server_down_stamp = 0;
static int server_goes_down_secs = 10;
static int server_broadcast_secs = 60;
static int ipx_flags = 0;
static int handle_all_sap_typs=HANDLE_ALL_SAP_TYPS;
static int nearest_request_flag=0;
#if IN_NWROUTED
@ -410,20 +415,21 @@ typedef struct {
ipxAddr_t addr; /* address of client */
time_t last_time; /* time of last wdog packet sent */
int counter; /* max. 11 packets */
} CONN;
} CONNECTION;
static CONN conns[MAX_CONNECTIONS];
static int max_connections=MAX_CONNECTIONS;
static CONNECTION *connections=NULL;
static int hi_conn=0; /* highest connection nr in use */
static void insert_wdog_conn(int conn, ipxAddr_t *adr)
{
if (conn > 0 && conn <= MAX_CONNECTIONS) {
CONN *c;
if (conn > 0 && conn <= max_connections) {
CONNECTION *c;
while (hi_conn < conn) {
c=&(conns[hi_conn++]);
memset(c, 0, sizeof(CONN));
c=&(connections[hi_conn++]);
memset(c, 0, sizeof(CONNECTION));
}
c=&(conns[conn-1]);
c=&(connections[conn-1]);
c->last_time = akttime_stamp;
c->counter = 0;
if (NULL != adr) memcpy(&(c->addr), adr, sizeof(ipxAddr_t));
@ -436,7 +442,7 @@ static void modify_wdog_conn(int conn, int mode)
/* mode = 99 : remove wdog */
{
if (conn > 0 && --conn < hi_conn) {
CONN *c=&(conns[conn]);
CONNECTION *c=&(connections[conn]);
if (mode < 99) {
switch (mode) {
case 1 : /* activate Wdog */
@ -450,10 +456,10 @@ static void modify_wdog_conn(int conn, int mode)
break;
} /* switch */
} else if (mode == 99) { /* remove */
memset(c, 0, sizeof(CONN));
memset(c, 0, sizeof(CONNECTION));
if (conn + 1 == hi_conn) {
while (hi_conn) {
c=&(conns[hi_conn-1]);
c=&(connections[hi_conn-1]);
if (!c->last_time) hi_conn--;
else break;
}
@ -466,7 +472,7 @@ static void send_wdogs()
{
int k = hi_conn;
while (k--) {
CONN *c = &(conns[k]);
CONNECTION *c = &(connections[k]);
if (c->last_time) {
time_t t_diff = akttime_stamp - c->last_time;
if ( (c->counter && t_diff > 50)
@ -491,7 +497,7 @@ static void send_wdogs()
static void send_bcasts(int conn)
{
if (conn > 0 && --conn < hi_conn) {
CONN *c = &(conns[conn]);
CONNECTION *c = &(connections[conn]);
ipxAddr_t adr;
memcpy(&adr, &(c->addr), sizeof(ipxAddr_t));
U16_TO_BE16(GET_BE16(adr.sock)+2, adr.sock);
@ -563,9 +569,7 @@ static void handle_sap(int fd,
/* if (hops < 16) hops++; */
XDPRINTF((2,0, "TYP=%2d,hops=%2d, Addr=%s, Name=%s", type, hops,
visable_ipx_adr(ad), name));
#if !HANDLE_ALL_SAP_TYPS
if (type == 4) { /* from Fileserver */
#endif
if (handle_all_sap_typs || type == 4) { /* from Fileserver */
if (16 == hops) {
/* shutdown */
XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name));
@ -574,9 +578,7 @@ static void handle_sap(int fd,
get_server_data((char*)name, ad, from_addr);
insert_delete_server(name, type, ad, from_addr, hops, 0, 0);
}
#if !HANDLE_ALL_SAP_TYPS
}
#endif
p+=sizeof(SAPS);
} /* while */
} else {
@ -761,14 +763,34 @@ static void handle_event(int fd, uint16 socknr, int slot)
XDPRINTF((2,0, "WDOG Packet len=%d connid=%d, status=%d",
(int)ud.udata.len, (int) ipx_data_buff.wdog.connid,
(int)ipx_data_buff.wdog.status));
if ('Y' == ipx_data_buff.wdog.status)
modify_wdog_conn(ipx_data_buff.wdog.connid, 0);
if ('Y' == ipx_data_buff.wdog.status) {
if (max_connections < 256)
modify_wdog_conn(ipx_data_buff.wdog.connid, 0);
else {
int k=-1;
while (++k < hi_conn) {
CONNECTION *c=&(connections[k]);
if (IPXCMPNODE(c->addr.node, source_adr.node)){
modify_wdog_conn(k+1, 0);
break;
}
}
}
}
} else if ( 2 < ud.udata.len
&& ipx_data_buff.data[0] == 0x11
&& ipx_data_buff.data[1] == 0x11 ) {
/* now we make an echo of this data */
send_ipx_data(sockfd[WDOG_SLOT],
17, ud.udata.len, ud.udata.buf, &source_adr, "ECHO");
} else {
uint8 *p = (uint8*)&ipx_data_buff;
int k = 0;
XDPRINTF((1, 2, "UNKNOWN from WDOG sock"));
while (k++ < ud.udata.len){
XDPRINTF((1, 3, " %x", (int) *p++));
}
XDPRINTF((1, 1, NULL));
}
break;
#endif
@ -866,48 +888,49 @@ static void get_ini(int full)
}
break;
case 4 :
if (full) {
if (anz_net_devices < MAX_NET_DEVICES &&
(!anz_net_devices || anz > 2) ) {
NW_NET_DEVICE **pnd=&(net_devices[anz_net_devices++]);
NW_NET_DEVICE *nd=*pnd=
(NW_NET_DEVICE*)xmalloc(sizeof(NW_NET_DEVICE));
memset(nd, 0, sizeof(NW_NET_DEVICE));
nd->ticks = 1;
nd->frame = IPX_FRAME_8023;
new_str(nd->devname, "eth0");
case 4 : if (full && ( (!count_net_devices) || anz > 2) ) {
NW_NET_DEVICE **pnd;
NW_NET_DEVICE *nd;
if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1)
sscanf(inhalt, "%lx", &nd->net);
if (count_net_devices >= max_net_devices)
realloc_net_devices();
if (nd->net && (nd->net == internal_net)) {
errorp(11, "Get_ini", "device net 0x%lx = internal net", nd->net);
exit(1);
}
pnd=&(net_devices[count_net_devices++]);
nd=*pnd=(NW_NET_DEVICE*)
xcmalloc(sizeof(NW_NET_DEVICE));
nd->ticks = 1;
nd->frame = IPX_FRAME_8023;
new_str(nd->devname, "eth0");
if (anz > 1)
new_str(nd->devname, inhalt2);
if (sscanf(inhalt, "%ld%c", &nd->net, &dummy) != 1)
sscanf(inhalt, "%lx", &nd->net);
if (anz > 2) {
upstr(inhalt3);
if (!strcmp(inhalt3, "AUTO"))
nd->frame=-1;
if (!strcmp(inhalt3, "802.3"))
nd->frame=IPX_FRAME_8023;
else if (!strcmp(inhalt3, "802.2"))
nd->frame=IPX_FRAME_8022;
else if (!strcmp(inhalt3, "SNAP"))
nd->frame=IPX_FRAME_SNAP;
else if (!strcmp(inhalt3, "ETHERNET_II"))
nd->frame=IPX_FRAME_ETHERII;
# ifdef IPX_FRAME_TR_8022
else if (!strcmp(inhalt3, "TOKEN"))
nd->frame=IPX_FRAME_TR_8022;
# endif
}
if (anz > 3) nd->ticks = atoi(inhalt4);
if (nd->net && (nd->net == internal_net)) {
errorp(11, "Get_ini", "device net 0x%lx = internal net", nd->net);
exit(1);
}
if (anz > 1)
new_str(nd->devname, inhalt2);
if (anz > 2) {
upstr(inhalt3);
if (!strcmp(inhalt3, "AUTO"))
nd->frame=-1;
if (!strcmp(inhalt3, "802.3"))
nd->frame=IPX_FRAME_8023;
else if (!strcmp(inhalt3, "802.2"))
nd->frame=IPX_FRAME_8022;
else if (!strcmp(inhalt3, "SNAP"))
nd->frame=IPX_FRAME_SNAP;
else if (!strcmp(inhalt3, "ETHERNET_II"))
nd->frame=IPX_FRAME_ETHERII;
# ifdef IPX_FRAME_TR_8022
else if (!strcmp(inhalt3, "TOKEN"))
nd->frame=IPX_FRAME_TR_8022;
# endif
}
if (anz > 3) nd->ticks = atoi(inhalt4);
}
break;
@ -915,7 +938,17 @@ static void get_ini(int full)
break;
#endif
case 69 : handle_all_sap_typs=atoi(inhalt);
break;
#if !IN_NWROUTED
case 60 : if (full) { /* connections */
max_connections=atoi(inhalt);
if (max_connections < 5)
max_connections=MAX_CONNECTIONS;
}
break;
case 104 : /* nwclient */
if (client_mode && atoi(inhalt))
client_mode++;
@ -972,12 +1005,12 @@ static void get_ini(int full)
#ifdef LINUX
# if INTERNAL_RIP_SAP
no_internal = !internal_net;
if (no_internal && anz_net_devices > 1) {
if (no_internal && count_net_devices > 1) {
errorp(11, "Get_ini", "No internal net, but more than 1 Device specified");
exit(1);
}
init_ipx(internal_net, node, ipxdebug, ipx_flags);
for (k=0; k < anz_net_devices; k++){
for (k=0; k < count_net_devices; k++){
NW_NET_DEVICE *nd=net_devices[k];
int result;
uint8 frname[30];
@ -1012,7 +1045,7 @@ static void get_ini(int full)
#if INTERNAL_RIP_SAP
if (no_internal) {
errorp(10, "WARNING:No use of internal net", NULL);
} else if (!anz_net_devices) {
} else if (!count_net_devices) {
errorp(10, "WARNING:No external devices specified", NULL);
}
print_routing_info(1);
@ -1074,7 +1107,7 @@ static void close_all(void)
# if INTERNAL_RIP_SAP
#if 0
if (!(ipx_flags&1)) {
for (j=0; j<anz_net_devices;j++) {
for (j=0; j<count_net_devices;j++) {
NW_NET_DEVICE *nd=net_devices[j];
if (nd->is_up) {
XDPRINTF((1, 0, "Close Device=%s, frame=%d",
@ -1231,6 +1264,9 @@ int main(int argc, char **argv)
init_tools(IN_PROG, init_mode);
set_sigs(0);
get_ini(1);
#if !IN_NWROUTED
connections=(CONNECTION*)xcmalloc(max_connections*sizeof(CONNECTION));
#endif
j=-1;
while (++j < NEEDED_POLLS) {
polls[j].events = POLLIN|POLLPRI;
@ -1286,7 +1322,9 @@ int main(int argc, char **argv)
#endif
while (!server_is_down) {
int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs);
#if !IN_NWROUTED
int call_wdog=0;
#endif
time(&akttime_stamp);
#if !IN_NWROUTED
if (fl_got_sigchld) {
@ -1299,8 +1337,10 @@ int main(int argc, char **argv)
if (WIFSIGNALED(stat_loc)) status=-99;
}
if (pid == pid_nwbind || pid == pid_ncpserv) {
errorp(1, "CHILD died", "Child=%s, result=%d",
(pid==pid_nwbind) ? "NWBIND" : "NCPSERV", status);
errorp(1, "CHILD died", "Child=%s, %s=%d",
(pid==pid_nwbind) ? "NWBIND" : "NCPSERV",
(status==-99) ? "got signal" : "result" ,
(status==-99) ? WTERMSIG(stat_loc) : status);
down_server();
} else
errorp(1, "unknown CHILD died", NULL);
@ -1441,6 +1481,10 @@ int main(int argc, char **argv)
close_all();
fprintf(stderr, "\nNWE-%s is down now !!\n", prog_name_typ);
exit_tools();
#if !IN_NWROUTED
xfree(connections);
#endif
return(0);
}

View File

@ -37,8 +37,9 @@ typedef struct {
} NW_NET_DEVICE;
/* <========== DEVICES ==========> */
extern int anz_net_devices;
extern NW_NET_DEVICE *net_devices[];
extern int count_net_devices;
extern int max_net_devices;
extern NW_NET_DEVICE **net_devices;
/* <======== SOCKETS =========> */
#if !IN_NWROUTED
@ -99,5 +100,6 @@ extern void insert_delete_server(uint8 *name,
int flags);
extern int dont_send_wdog(ipxAddr_t *addr);
extern void realloc_net_devices(void);
extern int test_ins_device_net(uint32 rnet);
#endif

View File

@ -1,4 +1,4 @@
/* nwvolume.c 01-Feb-97 */
/* nwvolume.c 17-Jun-97 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -29,10 +29,15 @@
#include <utime.h>
#include "nwfname.h"
#include "nwvolume.h"
NW_VOL nw_volumes[MAX_NW_VOLS];
int used_nw_volumes=0;
NW_VOL *nw_volumes=NULL;
int used_nw_volumes=0;
uint8 *home_dir=NULL;
int home_dir_len=0;
static int max_nw_vols=MAX_NW_VOLS;
static void volume_to_namespace_map(int volume, NW_VOL *vol)
{
@ -56,9 +61,15 @@ void nw_init_volumes(FILE *f)
int k = -1;
if (!volumes_is_init) {
volumes_is_init++;
while (++k < MAX_NW_VOLS) memset(&(nw_volumes[k]), 0, sizeof(NW_VOL));
rewind(f);
if (get_ini_entry(f, 61, buff, sizeof(buff))) {
max_nw_vols=atoi(buff);
if (max_nw_vols < 2)
max_nw_vols=MAX_NW_VOLS;
}
nw_volumes=(NW_VOL*)xcmalloc(max_nw_vols*sizeof(NW_VOL));
} else {
while (++k < MAX_NW_VOLS) {
while (++k < max_nw_vols) {
int i = -1;
while (++i < nw_volumes[k].maps_count)
xfree(nw_volumes[k].dev_namespace_maps[i]);
@ -68,7 +79,7 @@ void nw_init_volumes(FILE *f)
rewind(f);
used_nw_volumes = 0;
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
if ( what == 1 && used_nw_volumes < MAX_NW_VOLS && strlen((char*)buff) > 3){
if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){
uint8 sysname[256];
uint8 unixname[256];
char optionstr[256];
@ -78,7 +89,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);
up_fn(sysname);
new_str(vol->sysname, sysname);
if (1 == (len = strlen((char*)unixname)) && unixname[0] == '~') {
vol->options |= VOL_OPTION_IS_HOME;
@ -149,12 +160,16 @@ void nw_setup_home_vol(int len, uint8 *fn)
int k=used_nw_volumes;
uint8 unixname[258];
unixname[0] = '\0';
xfree(home_dir);
home_dir_len=0;
if (len > 0) {
strmaxcpy(unixname, fn, len);
if (unixname[len-1] != '/') {
unixname[len++] = '/';
unixname[len] = '\0';
}
new_str(home_dir, unixname);
home_dir_len=len;
}
while (k--) { /* now set all HOME volumes */
if (nw_volumes[k].options & VOL_OPTION_IS_HOME) {
@ -243,7 +258,7 @@ int nw_get_volume_number(uint8 *volname, int namelen)
uint8 vname[255];
int j = used_nw_volumes;
strmaxcpy(vname, volname, namelen);
upstr(vname);
up_fn(vname);
while (j--) {
if (!strcmp((char*)nw_volumes[j].sysname, (char*)vname)) {
result = j;
@ -265,7 +280,7 @@ int nw_get_volume_name(int volnr, uint8 *volname)
} else result= strlen((char*)nw_volumes[volnr].sysname);
} else {
if (NULL != volname) *volname = '\0';
if (volnr < MAX_NW_VOLS) result=0;
if (volnr < max_nw_vols) result=0;
}
if (nw_debug > 4) {
uint8 xvolname[10];

View File

@ -1,4 +1,4 @@
/* nwvolume.h 17-Jan-97 */
/* nwvolume.h 17-Jun-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -67,8 +67,10 @@ struct fs_usage {
long fsu_ffree; /* Free file nodes. */
};
extern NW_VOL nw_volumes[MAX_NW_VOLS];
extern NW_VOL *nw_volumes;
extern int used_nw_volumes;
extern uint8 *home_dir;
extern int home_dir_len;
extern void nw_init_volumes(FILE *f);
extern void nw_setup_home_vol(int len, uint8 *fn);

153
tools.c
View File

@ -1,4 +1,4 @@
/* tools.c 10-Apr-97 */
/* tools.c 08-Jun-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -16,8 +16,10 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "net.h"
#include <stdarg.h>
#include <syslog.h>
#ifndef LINUX
extern int _sys_nerr;
@ -28,7 +30,10 @@ extern char *_sys_errlist[];
int nw_debug=0;
uint32 debug_mask=0; /* special debug masks */
FILE *logfile=stderr;
static FILE *logfile=stderr;
static int use_syslog=0; /* 1 = use syslog for all loggings
* 2 = only for errors
*/
static int in_module=0; /* in which process i am ? */
static int connection=0; /* which connection (nwconn) */
@ -43,6 +48,7 @@ static char *modnames[] =
"NWBIND",
"NWROUTED" };
static char *get_modstr(void)
{
return(modnames[in_module]);
@ -97,20 +103,6 @@ int x_x_xnewstr(uint8 **p, uint8 *s)
return (len);
}
void dprintf(char *p, ...)
{
va_list ap;
if (nw_debug){
fprintf(logfile, "%-8s %d:", get_modstr(), connection);
va_start(ap, p);
vfprintf(logfile, p, ap);
va_end(ap);
fprintf(logfile, "\n");
fflush(logfile);
fflush(logfile);
}
}
void xdprintf(int dlevel, int mode, char *p, ...)
/* mode flags
* 0x01 : no 'begin line'
@ -119,23 +111,58 @@ void xdprintf(int dlevel, int mode, char *p, ...)
*/
{
va_list ap;
static char *buffered=NULL;
int errnum = errno;
if (nw_debug >= dlevel) {
if (!(mode & 1))
fprintf(logfile, "%-8s %d:", get_modstr(), connection);
if (p) {
va_start(ap, p);
vfprintf(logfile, p, ap);
va_end(ap);
if (use_syslog==1) {
char buf[2048]; /* should be ever big enough */
char *pb=buf;
if (buffered) {
strcpy(buf, buffered);
xfree(buffered);
pb+=strlen(buf);
}
if (p) {
int l;
va_start(ap, p);
l=vsprintf(pb, p, ap);
va_end(ap);
pb+=l;
}
if (mode & 0x10) {
int l=sprintf(pb, ", errno=%d", errnum);
pb+=l;
if (errnum > 0 && errnum < _sys_nerr)
l=sprintf(pb, " (%s)", _sys_errlist[errnum]);
}
if (!(mode & 2)) {
char identstr[200];
sprintf(identstr, "%-8s %d", get_modstr(), connection);
openlog(identstr, LOG_CONS, LOG_DAEMON);
syslog(LOG_DEBUG, buf);
closelog();
} else {
int l=strlen(buf);
buffered=xmalloc(l+1);
strcpy(buffered, buf);
}
} else {
if (!(mode & 1))
fprintf(logfile, "%-8s %d:", get_modstr(), connection);
if (p) {
va_start(ap, p);
vfprintf(logfile, p, ap);
va_end(ap);
}
if (mode & 0x10) {
fprintf(logfile, ", errno=%d", errnum);
if (errnum > 0 && errnum < _sys_nerr)
fprintf(logfile, " (%s)", _sys_errlist[errnum]);
}
if (!(mode & 2))
fprintf(logfile, "\n");
fflush(logfile);
}
if (mode & 0x10) {
fprintf(logfile, ", errno=%d", errnum);
if (errnum > 0 && errnum < _sys_nerr)
fprintf(logfile, " (%s)", _sys_errlist[errnum]);
}
if (!(mode & 2))
fprintf(logfile, "\n");
fflush(logfile);
}
}
@ -155,6 +182,24 @@ void errorp(int mode, char *what, char *p, ...)
sprintf(errbuf, "errno=%d", errnum);
else
errbuf[0] = '\0';
if (use_syslog) {
int prio=(mode) ? LOG_CRIT : LOG_ERR;
char identstr[200];
char buf[2048];
int l=sprintf(buf, "%s:%s ", what, errstr);
if (p) {
va_start(ap, p);
vsprintf(buf+l, p, ap);
va_end(ap);
}
sprintf(identstr, "%-8s %d", get_modstr(), connection);
openlog(identstr, LOG_CONS, LOG_DAEMON);
syslog(prio, buf);
closelog();
if (!mode) return;
lologfile=stderr;
}
while (1) {
if (mode==1) fprintf(lologfile, "\n!! %-8s %d:PANIC !!\n", get_modstr(), connection);
fprintf(lologfile, "%-8s %d:%s:%s\n", get_modstr(), connection, what, errstr);
@ -268,7 +313,7 @@ int get_ini_int(int what)
uint8 buff[30];
int i;
if (get_ini_entry(NULL, what, buff, sizeof(buff))
&& 1==sscanf((char*)buff, "%d", &i) ) return(i);
&& 1==sscanf((char*)buff, "%i", &i) ) return(i);
return(-1);
}
@ -288,10 +333,7 @@ void get_ini_debug(int module)
static void sig_segv(int isig)
{
char *s= "!!!! PANIC signal SIGSEGV at pid=%d !!!!!\n" ;
XDPRINTF((0, 0, s, my_pid));
fprintf(stderr, "\n");
fprintf(stderr, s, my_pid);
errorp(11, "!!! SIG_SEGV !!!", "at pid=%d", my_pid);
#if 0
(*sigsegv_func)(isig);
#endif
@ -369,14 +411,20 @@ void init_tools(int module, int options)
sig = SIGHUP;
} else if (options == 2) { /* kill prog */
sig = SIGTERM;
} else if (options == 3) { /* kill prog */
} else if (options == 3) { /* update tables */
sig = SIGUSR1;
} else {
errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" ,
kill_pid, pidfn);
exit(1);
}
if (kill_pid > 1) kill(kill_pid, sig);
if (kill_pid > 1) {
kill(kill_pid, sig);
if (sig == SIGUSR1) { /* we try twice */
sleep(2);
kill(kill_pid, sig);
}
}
exit(0);
} else if (options == 1 || options == 2 || options == 3) {
errorp(11, "INIT", "Program not running yet" );
@ -391,7 +439,9 @@ void init_tools(int module, int options)
strmaxcpy((uint8*)logfilename, (uint8*)buf, sizeof(logfilename)-1);
withlog++;
} else if (202 == what) {
new_log = atoi((char*)buf);
int flags = hextoi((char*)buf);
new_log=flags&1;
use_syslog=(flags&2) ? 2 : 0;
} else if (100+module == what) {
get_debug_level(buf);
}
@ -400,18 +450,22 @@ void init_tools(int module, int options)
}
if (dodaemon) {
if (!withlog) strcpy(logfilename, "./nw.log");
if (!strcmp(logfilename, "syslog"))
use_syslog=1;
if (NWSERV == module || NWROUTED == module) { /* now make daemon */
int fd=fork();
if (fd) exit((fd > 0) ? 0 : 1);
my_pid=getpid();
}
if (new_log && (NWSERV == module || NWROUTED == module))
unlink(logfilename);
if (NULL == (logfile = fopen(logfilename, "a"))) {
logfile = stderr;
errorp(1, "INIT", "Cannot open logfile='%s'",logfilename);
exit(1);
if (use_syslog != 1){
if (new_log && (NWSERV == module || NWROUTED == module))
unlink(logfilename);
if (NULL == (logfile = fopen(logfilename, "a"))) {
logfile = stderr;
errorp(1, "INIT", "Cannot open logfile='%s'",logfilename);
exit(1);
}
}
if (NWSERV == module || NWROUTED == module) {
creat_pidfile();
@ -482,6 +536,14 @@ int hextoi(char *buf)
return(i);
}
unsigned int atou(char *buf)
{
unsigned int u;
if (!buf || (1 != sscanf(buf, "%i", &u)))
u=0;
return(u);
}
char *hex_str(char *buf, uint8 *s, int len)
{
char *pp=buf;
@ -550,4 +612,3 @@ int find_station_match(int entry, ipxAddr_t *addr)
return(matched);
}

View File

@ -1,4 +1,4 @@
/* tools.h : 29-Sep-96 */
/* tools.h : 08-Jun-97 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
*
@ -40,7 +40,6 @@ extern int strmaxcpy(uint8 *dest, uint8 *source, int len);
#define xstrcpy(d, s) strmaxcpy((d), (s), sizeof(d)-1)
#define xstrmaxcpy(d, s, len) strmaxcpy((d), (s), min(sizeof(d)-1, (len)) )
extern void dprintf(char *p, ...);
extern void xdprintf(int dlevel, int mode, char *p, ...);
extern void errorp(int mode, char *what, char *p, ...);
extern FILE *open_nw_ini(void);
@ -60,6 +59,7 @@ extern uint8 *downstr(uint8 *ss);
extern uint8 *upstr(uint8 *ss);
extern int hextoi(char *buf);
extern unsigned int atou(char *buf);
extern char *hex_str(char *buf, uint8 *s, int len);
extern int name_match(uint8 *s, uint8 *p);
@ -67,17 +67,14 @@ extern int name_match(uint8 *s, uint8 *p);
extern uint8 *station_fn;
extern int find_station_match(int entry, ipxAddr_t *addr);
extern int nw_debug;
extern uint32 debug_mask;
#include "debmask.h"
#if DO_DEBUG
# define DPRINTF(x) dprintf x
# define XDPRINTF(x) xdprintf x
# define D() XDPRINTF((3, 0, "Z: %d" , __LINE__));
# define MDEBUG(mask, x) if (mask & debug_mask) x
#else
# define DPRINTF(x) /* */
# define XDPRINTF(x) /* */
# define D() /* */
# define MDEBUG(mask, x) /* */

View File

@ -1,5 +1,4 @@
/* unxfile.h: 20-Nov-96*/
/* unxfile.h: 18-Jun-97*/
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
@ -16,8 +15,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _UNXFILE_H_
#define _UNXFILE_H_ 1
extern int unx_mvdir(uint8 *oldname, uint8 *newname);
extern int unx_mvfile(uint8 *oldname, uint8 *newname);
extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname);
#endif