From 70cf9be9411274f92163f1d8e43e1e4138f2227e Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 13 Nov 2011 00:38:58 +0100 Subject: [PATCH] mars_nwe-0.98.pl11 --- connect.c | 253 ++++++++++++------- connect.h | 37 +-- debmask.h | 3 +- doc/CHANGES | 37 ++- doc/CREDITS | 14 +- doc/NEWS | 11 + doc/README.NLS | 31 +++ doc/mars_nwe.lsm | 6 +- emutli.c | 25 +- examples/README.important | 17 ++ examples/README.kpatch1.3.56 | 29 --- examples/README.kpatch1.3.7x | 14 -- examples/config.h | 29 ++- examples/e.pck | Bin 368 -> 0 bytes examples/kpatch1.3.56 | 56 ----- examples/kpatch1.3.72 | 72 ------ examples/kpatch1.3.78 | 74 ------ examples/kpatch2.0.29 | 112 +++++++++ examples/nw.ini | 90 +++++-- examples/nw.ini.cnv.437 | Bin 0 -> 1024 bytes examples/nw.ini.cnv.cyr | Bin 0 -> 1024 bytes examples/nw.ini.cnv.min | Bin 0 -> 1024 bytes examples/patchme | 20 -- examples/unxcomm.c | 17 +- examples/xsockrt.c | 72 ++++++ makefile.unx | 20 +- nameos2.c | 81 +++--- namspace.c | 218 ++++++++++------ ncpserv.c | 143 +++++++---- net.h | 54 ++-- nwbind.c | 94 ++++--- nwclient.c | 27 +- nwconn.c | 475 +++++++++++++++++++++++++++-------- nwconn.h | 18 ++ nwdbm.c | 12 +- nwdbm.h | 2 + nwfile.c | 154 +++++++----- nwfile.h | 12 +- nwfname.c | 336 +++++++++++++++++++++++++ nwfname.h | 35 +++ nwqueue.c | 7 +- nwroute.c | 156 +++++++----- nwroute1.c | 22 +- nwserv.c | 176 ++++++++----- nwserv.h | 6 +- nwvolume.c | 33 ++- nwvolume.h | 6 +- tools.c | 153 +++++++---- tools.h | 7 +- unxfile.h | 7 +- 50 files changed, 2239 insertions(+), 1034 deletions(-) create mode 100644 doc/README.NLS create mode 100644 examples/README.important delete mode 100644 examples/README.kpatch1.3.56 delete mode 100644 examples/README.kpatch1.3.7x delete mode 100644 examples/e.pck delete mode 100644 examples/kpatch1.3.56 delete mode 100644 examples/kpatch1.3.72 delete mode 100644 examples/kpatch1.3.78 create mode 100644 examples/kpatch2.0.29 create mode 100644 examples/nw.ini.cnv.437 create mode 100644 examples/nw.ini.cnv.cyr create mode 100644 examples/nw.ini.cnv.min delete mode 100755 examples/patchme create mode 100644 examples/xsockrt.c create mode 100644 nwfname.c create mode 100644 nwfname.h diff --git a/connect.c b/connect.c index 429c8e6..33b120f 100644 --- a/connect.c +++ b/connect.c @@ -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; /* fr 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 :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); } diff --git a/connect.h b/connect.h index fd4fd5a..eb49e33 100644 --- a/connect.h +++ b/connect.h @@ -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; /* fr 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 diff --git a/debmask.h b/debmask.h index f71a767..7485f18 100644 --- a/debmask.h +++ b/debmask.h @@ -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 diff --git a/doc/CHANGES b/doc/CHANGES index a598b37..ebdfbed 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,6 +1,6 @@ Sorry, this is in German only. User important notes are in the NEWS file. -Aenderungen in mars_nwe bis zum : 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index be19f21..a7acb49 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -3,6 +3,9 @@ Sorry, but this list will *never* be complete. Michael Beddow translated doc for PIPE-FS +Thomas Behr + testings, wrote syslog stuff + Guntram Blohm testing router code on token ring wrote the 'crypted change password' routines ! @@ -10,18 +13,27 @@ Guntram Blohm Uwe Bonnes many testings+notes -Arne de Bruijn +Arne de Bruijn testings, exploring ncp mysterius (netx), notes Hardy Buchholz wrote HOWTO.ger +Csoma Csaba + testings+bugfixes + Ales Dryak his linware gave the kick Fritz Elfert gives bugreport and patches +Peter Gerhard + testings, bugreport, patches. + +Victor Khimenko + cyrillic filename patches + Ruedi Kneubuehler helping and testing for linux/sparc diff --git a/doc/NEWS b/doc/NEWS index a9ae1ad..532801a 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -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 !! diff --git a/doc/README.NLS b/doc/README.NLS new file mode 100644 index 0000000..a2910fa --- /dev/null +++ b/doc/README.NLS @@ -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 diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 266c3ce..5d9930a 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -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 diff --git a/emutli.c b/emutli.c index 63cf9d7..e3cb0f0 100644 --- a/emutli.c +++ b/emutli.c @@ -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 #include +#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)); diff --git a/examples/README.important b/examples/README.important new file mode 100644 index 0000000..64784ad --- /dev/null +++ b/examples/README.important @@ -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 diff --git a/examples/README.kpatch1.3.56 b/examples/README.kpatch1.3.56 deleted file mode 100644 index 586f198..0000000 --- a/examples/README.kpatch1.3.56 +++ /dev/null @@ -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 diff --git a/examples/README.kpatch1.3.7x b/examples/README.kpatch1.3.7x deleted file mode 100644 index aa7dbff..0000000 --- a/examples/README.kpatch1.3.7x +++ /dev/null @@ -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 diff --git a/examples/config.h b/examples/config.h index 5d3f00a..15a66df 100644 --- a/examples/config.h +++ b/examples/config.h @@ -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 */ diff --git a/examples/e.pck b/examples/e.pck deleted file mode 100644 index b4e9105033796ffd6f617f7b24a37d893eb3faaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 wcmYc-$Yjo7WME)qtkGZ~67Wo90P0|<0h0_$gmwKVtYlcL-~t5~FpPm10M`lxnE(I) diff --git a/examples/kpatch1.3.56 b/examples/kpatch1.3.56 deleted file mode 100644 index f71bff3..0000000 --- a/examples/kpatch1.3.56 +++ /dev/null @@ -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); diff --git a/examples/kpatch1.3.72 b/examples/kpatch1.3.72 deleted file mode 100644 index 6b8f7ea..0000000 --- a/examples/kpatch1.3.72 +++ /dev/null @@ -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) - { diff --git a/examples/kpatch1.3.78 b/examples/kpatch1.3.78 deleted file mode 100644 index 34bbb5a..0000000 --- a/examples/kpatch1.3.78 +++ /dev/null @@ -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) - { diff --git a/examples/kpatch2.0.29 b/examples/kpatch2.0.29 new file mode 100644 index 0000000..9b16cab --- /dev/null +++ b/examples/kpatch2.0.29 @@ -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) + { diff --git a/examples/nw.ini b/examples/nw.ini index 1b038dd..e44cb8e 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -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 +# 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 diff --git a/examples/nw.ini.cnv.437 b/examples/nw.ini.cnv.437 new file mode 100644 index 0000000000000000000000000000000000000000..c8fd0d607f90021e913c7e7660b0321bb5642c8d GIT binary patch literal 1024 zcmZQzWMXDvWn<^yMC+6cQE@6%&_`l#-T_m6KOcR8m$^Ra4i{)Y8_`)zddH zG%_|ZH8Z!cw6eCbwX=6{baHlab#wRd^z!!c_45x13RUz zF>}`JIdkXDU$Ah|;w4L$Enl&6)#^2C*R9{Mant54TeofBv2)k%J$v`>6@tZ Z-;R?0TiTi?PK2cYDUFEqzl3(_9{@~0{t*BG literal 0 HcmV?d00001 diff --git a/examples/nw.ini.cnv.cyr b/examples/nw.ini.cnv.cyr new file mode 100644 index 0000000000000000000000000000000000000000..cd5ac4387247c9abb4da8e61e2a6676ff34795db GIT binary patch literal 1024 zcmZQzWMXDvWn<^yMC+6cQE@6%&_`l#-T_m6KOcR8m$^Ra4i{)Y8_`)zddH zG%_|ZH8Z!cw6eCbwX=6{baHlab#wRd^z!!c_45x13L= z>o=@kx_igQ1^agH+O~bw%0)}|?rCl6?dj|9zI6G@)ng|P-@ASH{>>YA4qV*4c;<}B zv*%BrGj-my{d1?xVi;imAK83s|ACu_w;Vcn^!}aOckgZ3xarHkpTEC<{`CLrkH5dZ zo!xcyr`94UJ9BEv;?sFz10>H)ZOy=`&`|nmuRky!q(z!0_3;W$U)>J9h5cy=U*f z{Ra*nI(+2lvEwIT3FIOu#;;w!ar4&gJ9qEhM>p>SIE8)t{^RGb-+%u8`%iKF<4)g1 qrT+yB7cE}0blGxP^nqgU$p@|M^Fw!_#XgmvHlPM literal 0 HcmV?d00001 diff --git a/examples/nw.ini.cnv.min b/examples/nw.ini.cnv.min new file mode 100644 index 0000000000000000000000000000000000000000..2c61d71e45ec120f067f2ca05a7208f2f49df776 GIT binary patch literal 1024 zcmZQzWMXDvWn<^yMC+6cQE@6%&_`l#-T_m6KOcR8m$^Ra4i{)Y8_`)zddH zG%_|ZH8Z!cw6eCbwX=6{baHlab#wRd^z!!c_45x13RUz zF>}`JIdkXDU$Ah|;w4L$Enl&6)#^2C*R9{Mant54TeofBv2)k%J$v` $IPXDIR/P1 - echo "please rebuild the kernel" - fi -else - echo "linuxdir $LINUXDIR perhaps wrong ?" -fi - diff --git a/examples/unxcomm.c b/examples/unxcomm.c index e9c0d12..6de7165 100644 --- a/examples/unxcomm.c +++ b/examples/unxcomm.c @@ -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 #include @@ -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]; diff --git a/examples/xsockrt.c b/examples/xsockrt.c new file mode 100644 index 0000000..4fbfafc --- /dev/null +++ b/examples/xsockrt.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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])); +} + + diff --git a/makefile.unx b/makefile.unx index f1c1d5c..9154ee9 100644 --- a/makefile.unx +++ b/makefile.unx @@ -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) diff --git a/nameos2.c b/nameos2.c index 8e40ddf..046eadc 100644 --- a/nameos2.c +++ b/nameos2.c @@ -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 #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 diff --git a/namspace.c b/namspace.c index e945c53..d3b2a6d 100644 --- a/namspace.c +++ b/namspace.c @@ -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 #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); } diff --git a/ncpserv.c b/ncpserv.c index 0db91c2..74ed5f3 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -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); } diff --git a/net.h b/net.h index 7cbdab1..ba39c7a 100644 --- a/net.h +++ b/net.h @@ -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; diff --git a/nwbind.c b/nwbind.c index 68ca7b2..652f065 100644 --- a/nwbind.c +++ b/nwbind.c @@ -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); } diff --git a/nwclient.c b/nwclient.c index 6abfb28..358809c 100644 --- a/nwclient.c +++ b/nwclient.c @@ -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); } diff --git a/nwconn.c b/nwconn.c index dd94614..0b40370 100644 --- a/nwconn.c +++ b/nwconn.c @@ -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 + 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); diff --git a/nwconn.h b/nwconn.h index 601770a..5dc6584 100644 --- a/nwconn.h +++ b/nwconn.h @@ -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 diff --git a/nwdbm.c b/nwdbm.c index cf0c1e1..20a288c 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -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. */ diff --git a/nwdbm.h b/nwdbm.h index 7118885..f59eb06 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -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 diff --git a/nwfile.c b/nwfile.c index a2d0031..9bda323 100644 --- a/nwfile.c +++ b/nwfile.c @@ -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 + 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); }) diff --git a/nwfile.h b/nwfile.h index a1717d0..57380e7 100644 --- a/nwfile.h +++ b/nwfile.h @@ -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); diff --git a/nwfname.c b/nwfname.c new file mode 100644 index 0000000..9eb6601 --- /dev/null +++ b/nwfname.c @@ -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 + */ + +#include "net.h" +#include "unxfile.h" +#include "nwvolume.h" +#include +#include "nwfname.h" +#include + +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 diff --git a/nwfname.h b/nwfname.h new file mode 100644 index 0000000..e47d27b --- /dev/null +++ b/nwfname.h @@ -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 diff --git a/nwqueue.c b/nwqueue.c index 66d7b60..891a017 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -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 */ diff --git a/nwroute.c b/nwroute.c index 6ab4c39..d188c41 100644 --- a/nwroute.c +++ b/nwroute.c @@ -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; diff --git a/nwroute1.c b/nwroute1.c index 5cca716..fa8f7fc 100644 --- a/nwroute1.c +++ b/nwroute1.c @@ -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 */ { diff --git a/nwserv.c b/nwserv.c index 4d92e43..0fb2fc6 100644 --- a/nwserv.c +++ b/nwserv.c @@ -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; jis_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); } diff --git a/nwserv.h b/nwserv.h index b9cc3eb..933a0b2 100644 --- a/nwserv.h +++ b/nwserv.h @@ -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 diff --git a/nwvolume.c b/nwvolume.c index 9e4fd44..8cd0c0e 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -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 +#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]; diff --git a/nwvolume.h b/nwvolume.h index 67cd66f..2fb6e36 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -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); diff --git a/tools.c b/tools.c index 82bd2ea..76c2b7a 100644 --- a/tools.c +++ b/tools.c @@ -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 +#include #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); } - diff --git a/tools.h b/tools.h index c88765c..fccb8d1 100644 --- a/tools.h +++ b/tools.h @@ -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) /* */ diff --git a/unxfile.h b/unxfile.h index 090848d..393a2bc 100644 --- a/unxfile.h +++ b/unxfile.h @@ -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